約 5,873,675 件
https://w.atwiki.jp/intensity/pages/29.html
//----------------------------------------------------------------------------- // $Id DecklinkCaptureDlg.cpp,v 1.9 2006/04/11 01 11 07 ivanr Exp $ // // Desc DirectShow capture sample // // Copyright (c) Blackmagic Design 2005. All rights reserved. //----------------------------------------------------------------------------- #include "stdafx.h" #include "DecklinkCapture.h" #include "DecklinkCaptureDlg.h" #include initguid.h // TODO move this to a lib #include "DecklinkSample_uuids.h" #undef lstrlenW #ifdef _DEBUG #define new DEBUG_NEW #endif #define WM_GRAPHNOTIFYWM_APP+1// for Filter Graph event notification //----------------------------------------------------------------------------- // CAboutDlg //----------------------------------------------------------------------------- // CAboutDlg dialog used for App About class CAboutDlg public CDialog { public CAboutDlg(); // Dialog Data enum { IDD = IDD_ABOUTBOX }; protected virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected DECLARE_MESSAGE_MAP() }; CAboutDlg CAboutDlg() CDialog(CAboutDlg IDD) { } void CAboutDlg DoDataExchange(CDataExchange* pDX) { CDialog DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() //----------------------------------------------------------------------------- // CDecklinkCaptureDlg dialog //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Constructor // CDecklinkCaptureDlg CDecklinkCaptureDlg(CWnd* pParent /*=NULL*/) CDialog(CDecklinkCaptureDlg IDD, pParent) , m_pIVW(NULL) { m_hIcon = AfxGetApp()- LoadIcon(IDR_MAINFRAME); } //----------------------------------------------------------------------------- // DoDataExchange // void CDecklinkCaptureDlg DoDataExchange(CDataExchange* pDX) { CDialog DoDataExchange(pDX); DDX_Control(pDX, IDC_COMBO_VIDEOFORMATS, m_videoFormatCtrl); DDX_Control(pDX, IDC_COMBO_AUDIOFORMATS, m_audioFormatCtrl); DDX_Control(pDX, IDC_STATIC_PREVIEW, m_preview); DDX_Control(pDX, IDC_EDIT_CAPTUREFILE, m_captureFileCtrl); DDX_Control(pDX, IDC_COMBO_COMPRESSION, m_compressionCtrl); DDX_Control(pDX, IDC_COMBO_VIDEODEVICE, m_videoDeviceCtrl); DDX_Control(pDX, IDC_COMBO_AUDIODEVICE, m_audioDeviceCtrl); } BEGIN_MESSAGE_MAP(CDecklinkCaptureDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_CBN_SELCHANGE(IDC_COMBO_VIDEOFORMATS, OnCbnSelchangeComboVideoformats) ON_CBN_SELCHANGE(IDC_COMBO_AUDIOFORMATS, OnCbnSelchangeComboAudioformats) ON_BN_CLICKED(IDC_CHECK_AUDIOMUTE, OnBnClickedCheckAudiomute) ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnBnClickedButtonBrowse) ON_BN_CLICKED(IDC_BUTTON_CAPTURE, OnBnClickedButtonCapture) ON_BN_CLICKED(IDC_BUTTON_STOP, OnBnClickedButtonStop) ON_CBN_SELCHANGE(IDC_COMBO_COMPRESSION, OnCbnSelchangeComboCompression) ON_CBN_SELCHANGE(IDC_COMBO_VIDEODEVICE, OnCbnSelchangeComboVideodevice) ON_CBN_SELCHANGE(IDC_COMBO_AUDIODEVICE, OnCbnSelchangeComboAudiodevice) END_MESSAGE_MAP() //----------------------------------------------------------------------------- // CDecklinkCaptureDlg message handlers //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // OnInitDialog // Called before the dialog is displayed, use this message handler to initialise // our app BOOL CDecklinkCaptureDlg OnInitDialog() { CDialog OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu- AppendMenu(MF_SEPARATOR); pSysMenu- AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application s main window is not a dialog SetIcon(m_hIcon, TRUE);// Set big icon SetIcon(m_hIcon, FALSE);// Set small icon // create a basic capture graph and preview the incoming video m_pGraph = NULL; m_pVideoCapture = NULL; m_pAudioCapture = NULL; m_pVideoRenderer = NULL; m_pSmartT = NULL; m_pControl = NULL; m_pIVW = NULL; m_pMediaEvent = NULL; m_ROTRegister = 0; m_bAudioMute = FALSE; m_compressor = 0; m_bEnableCompressionCtrl = TRUE; m_captureFile = " Select File "; // initialise default video media type ZeroMemory( m_vihDefault, sizeof(m_vihDefault)); m_vihDefault.AvgTimePerFrame = 333667; m_vihDefault.bmiHeader.biWidth = 720; m_vihDefault.bmiHeader.biHeight = 486; m_vihDefault.bmiHeader.biBitCount = 16; m_vihDefault.bmiHeader.biCompression = YVYU ; // initialise default audio media type ZeroMemory( m_wfexDefault, sizeof(m_wfexDefault)); m_wfexDefault.nChannels = 2;// the only field of interest // retrieve last state QueryRegistry(); m_captureFileCtrl.SetWindowText(m_captureFile); EnableControls(); // create a preview graph // add the filters that will be used by all the graphs; preview, uncompressed capture, dv capture, // mpeg capture and windows media capture HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, reinterpret_cast void** ( m_pGraph)); if (SUCCEEDED(hr)) { #ifdef _DEBUG hr = CDSUtils AddGraphToRot(m_pGraph, m_ROTRegister); #endif hr = m_pGraph- QueryInterface(IID_IMediaControl, reinterpret_cast void** ( m_pControl)); if (SUCCEEDED(hr)) { // locate the video capture devices hr = PopulateDeviceControl( CLSID_VideoInputDeviceCategory, m_videoDeviceCtrl); if (SUCCEEDED(hr)) { hr = PopulateDeviceControl( CLSID_AudioInputDeviceCategory, m_audioDeviceCtrl); if (SUCCEEDED(hr)) { PWSTR pVideoName = (PWSTR)m_videoDeviceCtrl.GetItemData(m_videoDeviceCtrl.SetCurSel(0)); PWSTR pAudioName = (PWSTR)m_audioDeviceCtrl.GetItemData(m_audioDeviceCtrl.SetCurSel(0)); if (pVideoName pAudioName) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_VideoInputDeviceCategory, pVideoName, m_pVideoCapture); if (SUCCEEDED(hr)) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_AudioInputDeviceCategory, pAudioName, m_pAudioCapture); if (SUCCEEDED(hr)) { PopulateVideoControl();// populate the video format control with the video formats of the currently selected device PopulateAudioControl();// populate the audio format control with the audio formats of the currently selected device PopulateCompressionControl(); // locate video screen renderer for the preview window hr = CDSUtils AddFilter(m_pGraph, CLSID_VideoRendererDefault, L"Video Renderer", m_pVideoRenderer); if (SUCCEEDED(hr)) { hr = CreatePreviewGraph(); } } } } } } } } return TRUE; // return TRUE unless you set the focus to a control } //----------------------------------------------------------------------------- // DestroyWindow // Called when the window is being destroyed, clean up and free all resources. BOOL CDecklinkCaptureDlg DestroyWindow() { m_regUtils.Close(); #ifdef _DEBUG CDSUtils RemoveGraphFromRot(m_ROTRegister); #endif DestroyGraph(); SAFE_RELEASE(m_pControl); // Hide Video Window and remove owner. This has to be done prior to // destroying any window that displays video/still. if (m_pIVW) { m_pIVW- put_Visible(OAFALSE); m_pIVW- put_Owner(NULL); } SAFE_RELEASE(m_pIVW); SAFE_RELEASE(m_pMediaEvent); SAFE_RELEASE(m_pVideoRenderer); SAFE_RELEASE(m_pAudioCapture); SAFE_RELEASE(m_pVideoCapture); SAFE_RELEASE(m_pGraph); // free mediatypes attached to format controls int count = m_videoFormatCtrl.GetCount(); for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(item)); } count = m_audioFormatCtrl.GetCount(); for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_audioFormatCtrl.GetItemData(item)); } // release the device names attached to the item s data count = m_videoDeviceCtrl.GetCount(); for (item=0; item count; ++item) { PWSTR pName = (PWSTR)m_videoDeviceCtrl.GetItemData(item); delete [] pName; } count = m_audioDeviceCtrl.GetCount(); for (item=0; item count; ++item) { PWSTR pName = (PWSTR)m_audioDeviceCtrl.GetItemData(item); delete [] pName; } return CDialog DestroyWindow(); } //----------------------------------------------------------------------------- // OnSysCommand // void CDecklinkCaptureDlg OnSysCommand(UINT nID, LPARAM lParam) { if ((nID 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog OnSysCommand(nID, lParam); } } //----------------------------------------------------------------------------- // OnPaint // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CDecklinkCaptureDlg OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast WPARAM (dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect( rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog OnPaint(); } } //----------------------------------------------------------------------------- // HandleGraphEvent // At the moment we just read the event, discard it and release memory used to store it. void CDecklinkCaptureDlg HandleGraphEvent(void) { LONG lEventCode, lEventParam1, lEventParam2; if (!m_pMediaEvent) { return; } while (SUCCEEDED(m_pMediaEvent- GetEvent( lEventCode, reinterpret_cast LONG_PTR * ( lEventParam1), reinterpret_cast LONG_PTR * ( lEventParam2), 0))) { // just free memory associated with event m_pMediaEvent- FreeEventParams(lEventCode, lEventParam1, lEventParam2); } } //----------------------------------------------------------------------------- // WindowProc // Have to add our own message handling loop to handle events from the preview video // window and to pass Window events onto it - this is so it redraws itself correctly etc. LRESULT CDecklinkCaptureDlg WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_GRAPHNOTIFY HandleGraphEvent(); break; } // Pass all msgs to video window. vid window exists as child of static // picture frame. This ensures video window redraws itself etc. if (m_pIVW) { m_pIVW- NotifyOwnerMessage(reinterpret_cast LONG_PTR (m_hWnd) /* from me */, message, wParam, lParam); } return CDialog WindowProc(message, wParam, lParam); } //----------------------------------------------------------------------------- // OnQueryDragIcon // The system calls this function to obtain the cursor to display while the user drags // the minimized window. HCURSOR CDecklinkCaptureDlg OnQueryDragIcon() { return static_cast HCURSOR (m_hIcon); } //----------------------------------------------------------------------------- // CreatePreviewGraph // Create a graph to preview the input // NOTE There are many ways of building graphs, you could opt for the ICaptureGraphBuilder interface which would // make things are lot simpler, however it doesn t always build the most efficient graphs. HRESULT CDecklinkCaptureDlg CreatePreviewGraph() { HRESULT hr = S_OK; if (m_pGraph) { // locate smart-T // NOTE The smart-T appears to hold references to its upstream connections even when its input pin // is diconnected. The smart-T has to be removed from the graph in order to clear these references which // is why the filter is enumerated and added every time the preview graph is built and removed whenever // it is destroyed. ASSERT(NULL == m_pSmartT); hr = CDSUtils AddFilter(m_pGraph, CLSID_SmartTee, L"Smart Tee", m_pSmartT); if (SUCCEEDED(hr)) { // DV preview is slightly different to all other previews if (ENC_DV != m_compressionCtrl.GetItemData(m_compressionCtrl.GetCurSel())) { // uncompressed, mpeg and wm preview // create the following // // Decklink Video Capture - Smart-T - AVI Decompressor - Video Renderer // Decklink Audio Capture - Default Audio Renderer // // render the preview pin on the smart-T filter // first connect the Decklink video capture pin to the smart-T hr = CDSUtils ConnectFilters(m_pGraph, m_pVideoCapture, NULL, m_pSmartT, NULL); if (SUCCEEDED(hr)) { // now connect the preview pin of the smart-T to the video renderer hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Preview", m_pVideoRenderer, NULL); } } else { // DV Preview // create the following // // Decklink Video Capture - AVI Decompressor - Smart-T - Colour Space Converter - Video Renderer // Decklink Audio Capture - Default Audio Renderer // // this is a more efficient graph than created by the ICaptureGraphBuilder2 interface // add the AVI decompressor and colour space converter filters CComPtr IBaseFilter pAVIDecompressor = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_AVIDec, L"AVI Decompressor", pAVIDecompressor); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pColourSpaceConverter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_Colour, L"Color Space Converter", pColourSpaceConverter); if (SUCCEEDED(hr)) { // conect the Decklink video capture pin to the AVI decompressor hr = CDSUtils ConnectFilters(m_pGraph, m_pVideoCapture, NULL, pAVIDecompressor, NULL); if (SUCCEEDED(hr)) { // connect AVI decompressor to the smart-T hr = CDSUtils ConnectFilters(m_pGraph, pAVIDecompressor, NULL, m_pSmartT, NULL); if (SUCCEEDED(hr)) { // connect the preview pin of the smart-T to the colour space converter hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Preview", pColourSpaceConverter, NULL); if (SUCCEEDED(hr)) { // connect the colour space converter to the video renderer hr = CDSUtils ConnectFilters(m_pGraph, pColourSpaceConverter, NULL, m_pVideoRenderer, NULL); } } } } } } } } else { hr = E_POINTER; } if (SUCCEEDED(hr)) { // the video path has been connected, initialise the preview window InitialiseVideoPreview(); // optionally connect the audio path if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the mux hr = CDSUtils RenderFilter(m_pGraph, m_pAudioCapture, L"Capture"); } // run the graph so that we can preview the input video if (m_pControl) { hr = m_pControl- Run(); } else { hr = E_POINTER; } } return hr; } //----------------------------------------------------------------------------- // CreateCaptureGraph // Create a graph to capture the input HRESULT CDecklinkCaptureDlg CreateCaptureGraph() { HRESULT hr = S_OK; // tack the file writer onto the preview graph if (m_pGraph m_pControl) { // stop the graph as we are about to modify it m_pControl- Stop(); // remove the default audio renderer so the Decklink audio capture filter // can be connected to the AVI mux, we will not preview audio whilst capturing CComPtr IPin pIPinOutput = NULL; hr = CDSUtils GetPin(m_pAudioCapture, L"Capture", pIPinOutput); if (SUCCEEDED(hr)) { // to disconnect both pins must be disconnected // find the pin connected to the Decklink audio capture pin CComPtr IPin pIPinConnection = NULL; hr = pIPinOutput- ConnectedTo( pIPinConnection); if (SUCCEEDED(hr)) { // disconnect the pins hr = m_pGraph- Disconnect(pIPinOutput); hr = m_pGraph- Disconnect(pIPinConnection); // get the owning filter of the downstream pin and remove it from the graph PIN_INFO pinInfo = {0}; hr = pIPinConnection- QueryPinInfo( pinInfo); if (SUCCEEDED(hr)) { if (pinInfo.pFilter) { hr = m_pGraph- RemoveFilter(pinInfo.pFilter); pinInfo.pFilter- Release(); } } } } // retrieve the capture filename m_captureFileCtrl.GetWindowText(m_captureFile); // store filename USES_CONVERSION; WCHAR captureFile[MAX_PATH]; wcsncpy(captureFile, A2W(m_captureFile), MAX_PATH); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetString("CaptureFile", reinterpret_cast const BYTE* (captureFile), sizeof(captureFile))); // decide the type of capture graph to build switch (m_compressionCtrl.GetItemData(m_compressionCtrl.GetCurSel())) { default case ENC_NONE hr = CreateUncompressedCaptureGraph(); break; case ENC_DV hr = CreateDVCaptureGraph(); break; case ENC_WM hr = CreateWMCaptureGraph(); break; } if (FAILED(hr)) { // there was a problem building the capture graph, issue a message // and rebuild preview graph char buffer[128]; StringCbPrintfA(buffer, sizeof(buffer), "The error 0x%08lx was detected when creating the capture graph with the following file name \r\n\r\n %s ", hr, m_captureFile); MessageBox(buffer, _T("Error"), MB_ICONERROR); OnBnClickedButtonStop();// destroy broken capture graph, build preview graph and enable controls } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // CreateUncompressedCaptureGraph // Create an optimum uncompressed capture graph HRESULT CDecklinkCaptureDlg CreateUncompressedCaptureGraph() { HRESULT hr = S_OK; // uncompressed capture // locate the AVI mux and file writer filters and add them to the graph CComPtr IBaseFilter pAVIMux = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_AviDest , L"AVI Mux", pAVIMux); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pFileWriter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_FileWriter, L"File writer", pFileWriter); if (SUCCEEDED(hr)) { // set the output filename CComQIPtr IFileSinkFilter, IID_IFileSinkFilter pIFS = pFileWriter; if (pIFS) { USES_CONVERSION;// for T2W macro hr = pIFS- SetFileName(T2W(m_captureFile), NULL); if (SUCCEEDED(hr)) { // connect the smart-T capture pin to the mux hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Capture", pAVIMux, NULL); if (SUCCEEDED(hr)) { // connect the mux to the file writer hr = CDSUtils ConnectFilters(m_pGraph, pAVIMux, NULL, pFileWriter, NULL); if (SUCCEEDED(hr)) { // video path connected now optionally connect the audio path if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the mux hr = CDSUtils ConnectFilters(m_pGraph, m_pAudioCapture, L"Capture", pAVIMux, NULL); } if (SUCCEEDED(hr)) { m_pControl- Run(); } } } } } } } return hr; } //----------------------------------------------------------------------------- // CreateDVCaptureGraph // Create an optimum DV capture graph // NOTE that this will only work for SD HRESULT CDecklinkCaptureDlg CreateDVCaptureGraph() { HRESULT hr = S_OK; // locate the DV encoder, AVI mux and file writer filters and add them to the graph CComPtr IBaseFilter pDVEncoder = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_DVVideoEnc, L"DV Video Encoder", pDVEncoder); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pAVIMux = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_AviDest , L"AVI Mux", pAVIMux); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pFileWriter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_FileWriter, L"File writer", pFileWriter); if (SUCCEEDED(hr)) { // set the output filename CComQIPtr IFileSinkFilter, IID_IFileSinkFilter pIFS = pFileWriter; if (pIFS) { USES_CONVERSION;// for T2W macro hr = pIFS- SetFileName(T2W(m_captureFile), NULL); if (SUCCEEDED(hr)) { // configure the DV encoder CComQIPtr IDVEnc, IID_IDVEnc pIDV = pDVEncoder; if (pIDV) { // located a DV compression filter, set the format int videoFormat, dvFormat, resolution; hr = pIDV- get_IFormatResolution( videoFormat, dvFormat, resolution, FALSE, NULL); if (SUCCEEDED(hr)) { ASSERT(DVENCODERFORMAT_DVSD == dvFormat); ASSERT(DVENCODERRESOLUTION_720x480 == resolution); if ((DVENCODERVIDEOFORMAT_NTSC == videoFormat) (576 == m_vihDefault.bmiHeader.biHeight)) { // set the encoder to PAL if its NTSC videoFormat = DVENCODERVIDEOFORMAT_PAL; hr = pIDV- put_IFormatResolution(videoFormat, dvFormat, resolution, FALSE, NULL); } else if ((DVENCODERVIDEOFORMAT_PAL == videoFormat) (486 == m_vihDefault.bmiHeader.biHeight)) { // set the encoder to NTSC if its PAL videoFormat = DVENCODERVIDEOFORMAT_NTSC; hr = pIDV- put_IFormatResolution(videoFormat, dvFormat, resolution, FALSE, NULL); } } } if (SUCCEEDED(hr)) { // if the format is PAL, insert the Decklink field swap filter, PAL DV is the opposite // field order to PAL SD if (576 == m_vihDefault.bmiHeader.biHeight) { CComPtr IBaseFilter pPALFieldSwap = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_DecklinkFieldSwap, L"Decklink PAL Field Swap", pPALFieldSwap); if (SUCCEEDED(hr)) { // connect the smart-T capture pin to the PAL field swap filter hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Capture", pPALFieldSwap, NULL); if (SUCCEEDED(hr)) { // connect the field swap filter to the DV encoder hr = CDSUtils ConnectFilters(m_pGraph, pPALFieldSwap, NULL, pDVEncoder, NULL); } } } else { // connect the smart-T capture pin to the DV Encoder hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Capture", pDVEncoder, NULL); } if (SUCCEEDED(hr)) { // connect the DV encoder output to the AVI mux hr = CDSUtils ConnectFilters(m_pGraph, pDVEncoder, NULL, pAVIMux, NULL); if (SUCCEEDED(hr)) { // connect the mux to the file writer hr = CDSUtils ConnectFilters(m_pGraph, pAVIMux, NULL, pFileWriter, NULL); if (SUCCEEDED(hr)) { // video path connected now optionally connect the audio path if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the mux hr = CDSUtils ConnectFilters(m_pGraph, m_pAudioCapture, L"Capture", pAVIMux, NULL); } if (SUCCEEDED(hr)) { m_pControl- Run(); } } } } } } } } } } return hr; } //----------------------------------------------------------------------------- // CreateWMCaptureGraph // Create an optimum Windows Media capture graph HRESULT CDecklinkCaptureDlg CreateWMCaptureGraph() { HRESULT hr = S_OK; // locate the asf writer filter and add it to the graph CComPtr IBaseFilter pASFWriter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_WMAsfWriter, L"WM ASF Writer", pASFWriter); if (SUCCEEDED(hr)) { // set the output filename CComQIPtr IFileSinkFilter, IID_IFileSinkFilter pIFS = pASFWriter; if (pIFS) { USES_CONVERSION;// for T2W macro hr = pIFS- SetFileName(T2W(m_captureFile), NULL); if (SUCCEEDED(hr)) { hr = ConfigureWMEncoder(pASFWriter); } } if (SUCCEEDED(hr)) { if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the ASF writer hr = CDSUtils ConnectFilters(m_pGraph, m_pAudioCapture, pASFWriter, MEDIATYPE_Audio); } if (SUCCEEDED(hr)) { // connect the smart-T capture pin to the ASF writer hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, pASFWriter, MEDIATYPE_Video); if (SUCCEEDED(hr)) { m_pControl- Run(); } } } } return hr; } //----------------------------------------------------------------------------- // ConfigureWMEncoder // Configure the Windows Media encoder HRESULT CDecklinkCaptureDlg ConfigureWMEncoder(IBaseFilter* pASFWriter) { HRESULT hr = S_OK; // modify the video output resolution of a system profile if (pASFWriter) { // simple system profile encoding CComQIPtr IConfigAsfWriter, IID_IConfigAsfWriter pICW = pASFWriter; if (pICW) { //NOTE You could just use the following for a default system profile //hr = pICW- ConfigureFilterUsingProfileGuid(WMProfile_XXX);// RE wmsysprf.h //NOTE If you want video only capture you must modify the profile to remove the audio // otherwise encoding will fail // Load a system profile and modify the resolution of the video output // NOTE The scope of the encoding is enormous, this just demonstrates how to change // the output video resolution from 320x240 to something larger. // Changing the resolution affects coding performance, it is likely that the encoder will // start to drop frames after a while. Using WM9 codecs will probably improve performance // and that has been left to the reader... ;o) // // get a profile manager CComPtr IWMProfileManager pIWMProfileManager = NULL; hr = WMCreateProfileManager( pIWMProfileManager); if (SUCCEEDED(hr)) { // load a system profile to modify CComPtr IWMProfile pIWMProfile = NULL; // NOTE Any WMProfile_XXX could be used here, or create a custom profile from scratch hr = pIWMProfileManager- LoadProfileByID(WMProfile_V80_FAIRVBRVideo, pIWMProfile); if (SUCCEEDED(hr)) { // search the streams for the video stream and attempt to modify the video size DWORD cbStreams = 0; hr = pIWMProfile- GetStreamCount( cbStreams); if (SUCCEEDED(hr)) { IWMStreamConfig* pIWMStreamConfig = NULL; GUID streamType = {0}; DWORD stream; if (m_bAudioMute) { // remove the audio stream for video only capture for (stream=0; stream cbStreams; ++stream) { hr = pIWMProfile- GetStream(stream, pIWMStreamConfig); if (SUCCEEDED(hr)) { hr = pIWMStreamConfig- GetStreamType( streamType); if (SUCCEEDED(hr)) { if (MEDIATYPE_Audio == streamType) { if (SUCCEEDED(pIWMProfile- RemoveStream(pIWMStreamConfig))) { --cbStreams; } SAFE_RELEASE(pIWMStreamConfig); break; } } } } } for (stream=0; stream cbStreams; ++stream) { hr = pIWMProfile- GetStream(stream, pIWMStreamConfig); if (SUCCEEDED(hr)) { hr = pIWMStreamConfig- GetStreamType( streamType); if (SUCCEEDED(hr) (MEDIATYPE_Video == streamType)) { // found the video stream CComQIPtr IWMMediaProps, IID_IWMMediaProps pIWMMediaProps = pIWMStreamConfig; if (pIWMMediaProps) { // get the size of the media type WM_MEDIA_TYPE* pMediaType = NULL; DWORD cbMediaType = 0; hr = pIWMMediaProps- GetMediaType(pMediaType, cbMediaType); if (SUCCEEDED(hr)) { pMediaType = (WM_MEDIA_TYPE*)new char [cbMediaType]; if (pMediaType) { hr = pIWMMediaProps- GetMediaType(pMediaType, cbMediaType); if (SUCCEEDED(hr)) { BITMAPINFOHEADER* pbmih = NULL; if (WMFORMAT_VideoInfo == pMediaType- formattype) { WMVIDEOINFOHEADER* pvih = (WMVIDEOINFOHEADER*)pMediaType- pbFormat; pbmih = pvih- bmiHeader; } else if (WMFORMAT_MPEG2Video == pMediaType- formattype) { WMVIDEOINFOHEADER2* pvih = (WMVIDEOINFOHEADER2*) ((WMMPEG2VIDEOINFO*)pMediaType- pbFormat)- hdr; pbmih = pvih- bmiHeader; } if (pbmih) { // modify the video dimensions, set the property, reconfigure the stream // and then configure the ASF writer with this modified profile pbmih- biWidth = 640;// was 320; pbmih- biHeight = 480;// was 240; pbmih- biSizeImage = pbmih- biWidth * pbmih- biHeight * pbmih- biBitCount / 8;// NOTE This calculation is not correct for all bit depths hr = pIWMMediaProps- SetMediaType(pMediaType); if (SUCCEEDED(hr)) { // config the ASF writer filter to use this modified system profile hr = pIWMProfile- ReconfigStream(pIWMStreamConfig); if (SUCCEEDED(hr)) { hr = pICW- ConfigureFilterUsingProfile(pIWMProfile); } } } } delete [] (char*)pMediaType; } } } } SAFE_RELEASE(pIWMStreamConfig); } } } } } /* // modify other ASF writer properties IServiceProvider* pProvider = NULL; hr = pASFWriter- QueryInterface(IID_IServiceProvider, reinterpret_cast void** ( pProvider)); if (SUCCEEDED(hr)) { IID_IWMWriterAdvanced2* pWMWA2 = NULL; hr = pProvider- QueryService(IID_IID_IWMWriterAdvanced2, IID_IID_IWMWriterAdvanced2, reinterpret_cast void** ( pWMWA2)); if (SUCCEEDED(hr)) { // set the deinterlace mode pWMWA2- GetInputSetting(...); SAFE_RELEASE(pWMWA2); } SAFE_RELEASE(pProvider); } */ } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // DestroyGraph // Remove all intermediate filters, keep any Decklink and video render filters as // these are used by all the graphs. HRESULT CDecklinkCaptureDlg DestroyGraph() { HRESULT hr = S_OK; if (m_pGraph m_pControl) { m_pControl- Stop(); // release our outstanding reference on this filter so it can be removed from the graph SAFE_RELEASE(m_pSmartT); // retrieve the name of the capture device, don t remove it in this method PWSTR pNameVideoCapture = (PWSTR)m_videoDeviceCtrl.GetItemData(m_videoDeviceCtrl.GetCurSel()); PWSTR pNameAudioCapture = (PWSTR)m_audioDeviceCtrl.GetItemData(m_audioDeviceCtrl.GetCurSel()); CComPtr IEnumFilters pEnum = NULL; hr = m_pGraph- EnumFilters( pEnum); if (SUCCEEDED(hr)) { IBaseFilter* pFilter = NULL; while (S_OK == pEnum- Next(1, pFilter, NULL)) { FILTER_INFO filterInfo = {0}; hr = pFilter- QueryFilterInfo( filterInfo); if (SUCCEEDED(hr)) { SAFE_RELEASE(filterInfo.pGraph); if ((NULL == wcsstr(filterInfo.achName, pNameVideoCapture)) (NULL == wcsstr(filterInfo.achName, pNameAudioCapture)) (NULL == wcsstr(filterInfo.achName, L"Video Renderer"))) { hr = m_pGraph- RemoveFilter(pFilter); if (SUCCEEDED(hr)) { hr = pEnum- Reset(); } } } SAFE_RELEASE(pFilter); } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // InitialiseVideoPreview // In short get the video screen renderer to draw into the picture control, which is our preview window // the following code sets this up, in addition to adding the HandleGraphEvent and WindowProc methods // read the DXSDK docos for more detailed information void CDecklinkCaptureDlg InitialiseVideoPreview(void) { // modify the preview window if (m_pVideoRenderer) { if (NULL == m_pIVW) { if (SUCCEEDED(m_pVideoRenderer- QueryInterface(IID_IVideoWindow, reinterpret_cast void** ( m_pIVW)))) { // get the window to handle redraws, etc // Set msg drain of VideoWindow to point to our dialog window. The dialog s // window procedure then handles events from the VideoWindow. HRESULT hr = m_pIVW- put_MessageDrain(reinterpret_cast OAHWND (m_hWnd)); if (NULL == m_pMediaEvent) { // Make graph send WM_GRAPHNOTIFY when it wants our attention see "Learning // When an Event Occurs" in the DX9 documentation. hr = m_pGraph- QueryInterface(IID_IMediaEventEx, reinterpret_cast void** ( m_pMediaEvent)); if (SUCCEEDED(hr)) { hr = m_pMediaEvent- SetNotifyWindow(reinterpret_cast OAHWND (m_hWnd), WM_GRAPHNOTIFY, 0); } // object created for it. RECT rc; m_preview.GetClientRect( rc); m_pIVW- SetWindowPosition(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); // VideoWindow is a child window of the bounding rect hr = m_pIVW- put_WindowStyle(WS_CHILD); hr = m_pIVW- put_Owner(reinterpret_cast OAHWND (m_preview.GetSafeHwnd())); hr = m_pIVW- SetWindowForeground(-1); } } } } } //----------------------------------------------------------------------------- // PopulateDeviceControl // Fill device combo box with available devices of the specified category HRESULT CDecklinkCaptureDlg PopulateDeviceControl(const GUID* pCategory, CComboBox* pCtrl) { HRESULT hr = S_OK; if (pCategory pCtrl) { // first enumerate the system devices for the specifed class and filter name CComPtr ICreateDevEnum pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast void** ( pSysDevEnum)); if (SUCCEEDED(hr)) { CComPtr IEnumMoniker pEnumCat = NULL; hr = pSysDevEnum- CreateClassEnumerator(*pCategory, pEnumCat, 0); if (S_OK == hr) { IMoniker* pMoniker = NULL; bool Loop = true; while ((S_OK == pEnumCat- Next(1, pMoniker, NULL)) Loop) { IPropertyBag* pPropBag = NULL; hr = pMoniker- BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast void** ( pPropBag)); if (SUCCEEDED(hr)) { VARIANT varName; VariantInit( varName); hr = pPropBag- Read(L"FriendlyName", varName, 0); if (SUCCEEDED(hr)) { size_t len = wcslen(varName.bstrVal) + 1; PWSTR pName = new WCHAR [len]; StringCchCopyW(pName, len, varName.bstrVal); CW2AEX buf(varName.bstrVal); pCtrl- SetItemData(pCtrl- AddString(buf), (DWORD)pName); } VariantClear( varName); // contained within a loop, decrement the reference count SAFE_RELEASE(pPropBag); } SAFE_RELEASE(pMoniker); } } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // PopulateVideoControl // Fill video format combo box with supported video formats using the IAMStreamConfig // interface. HRESULT CDecklinkCaptureDlg PopulateVideoControl() { HRESULT hr = S_OK; if (m_pVideoCapture) { // free mediatypes attached to format controls int count = m_videoFormatCtrl.GetCount(); if (count) { for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(item)); } m_videoFormatCtrl.ResetContent(); } // locate the video capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pVideoCapture, MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // loop through all the capabilities (video formats) and populate the control int count, size; hr = pISC- GetNumberOfCapabilities( count, size); if (SUCCEEDED(hr)) { if (sizeof(VIDEO_STREAM_CONFIG_CAPS) == size) { AM_MEDIA_TYPE* pmt = NULL; VIDEO_STREAM_CONFIG_CAPS vscc; VIDEOINFOHEADER* pvih = NULL; for (int index=0; index count; ++index) { hr = pISC- GetStreamCaps(index, pmt, reinterpret_cast BYTE* ( vscc)); if (SUCCEEDED(hr)) { char buffer[128]; WORD PixelFormat; float FrameRate; ZeroMemory(buffer, sizeof(buffer)); pvih = (VIDEOINFOHEADER*)pmt- pbFormat; char* pPixelFormatLUT[] = {"4 2 2", "4 4 4"}; if (pvih- bmiHeader.biBitCount == 16) PixelFormat = 8; else if (pvih- bmiHeader.biBitCount == 20) PixelFormat = 10; else PixelFormat = pvih- bmiHeader.biBitCount; // provide a useful description of the formats if (486 == pvih- bmiHeader.biHeight) { if (417083 == pvih- AvgTimePerFrame) { StringCbPrintfA(buffer, sizeof(buffer), "NTSC %d-bit %s (3 2 pulldown removal)", PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "NTSC %d-bit %s", PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else if (576 == pvih- bmiHeader.biHeight) { StringCbPrintfA(buffer, sizeof(buffer), "PAL %d-bit %s", PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { char* pFrameRateFormat[] = {"%.2f", "%.0f"}; FrameRate = (float)(long)UNITS / pvih- AvgTimePerFrame; if ((720 == pvih- bmiHeader.biHeight) (59.94 FrameRate)) { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.2fp %d-bit %s (Overcranked 60p)", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.0fp %d-bit %s (Overcranked 60p)", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else if ((720 == pvih- bmiHeader.biHeight) (59.94 = FrameRate)) { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.2fp %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.0fp %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else if ((1080 == pvih- bmiHeader.biHeight) (50.00 = FrameRate)) { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.2fi %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.0fi %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.2fPsF %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.0fPsF %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } } // add the item description to combo box int n = m_videoFormatCtrl.AddString(buffer); // store media type pointer in item s data section m_videoFormatCtrl.SetItemData(n, (DWORD_PTR)pmt); // set default format if ((pvih- AvgTimePerFrame == m_vihDefault.AvgTimePerFrame) (pvih- bmiHeader.biWidth == m_vihDefault.bmiHeader.biWidth) (pvih- bmiHeader.biHeight == m_vihDefault.bmiHeader.biHeight) (pvih- bmiHeader.biBitCount == m_vihDefault.bmiHeader.biBitCount)) { m_videoFormatCtrl.SetCurSel(n); pISC- SetFormat(pmt); } } } } else { m_videoFormatCtrl.AddString("ERROR Unable to retrieve video formats"); } } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // PopulateAudioControl // Fill audio format combo box with supported audio formats using the IAMStreamConfig // interface. HRESULT CDecklinkCaptureDlg PopulateAudioControl() { HRESULT hr = S_OK; if (m_pAudioCapture) { // free mediatypes attached to format controls int count = m_audioFormatCtrl.GetCount(); if (count) { for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_audioFormatCtrl.GetItemData(item)); } m_audioFormatCtrl.ResetContent(); } // locate the audio capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pAudioCapture, MEDIATYPE_Audio, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // loop through all the capabilities (audio formats) and populate the control int count, size; hr = pISC- GetNumberOfCapabilities( count, size); if (SUCCEEDED(hr)) { if (sizeof(AUDIO_STREAM_CONFIG_CAPS) == size) { AM_MEDIA_TYPE* pmt = NULL; AUDIO_STREAM_CONFIG_CAPS ascc; WAVEFORMATEX* pwfex = NULL; for (int index=0; index count; ++index) { hr = pISC- GetStreamCaps(index, pmt, reinterpret_cast BYTE* ( ascc)); if (SUCCEEDED(hr)) { char buffer[32]; ZeroMemory(buffer, sizeof(buffer)); pwfex = (WAVEFORMATEX*)pmt- pbFormat; // provide a useful description of the formats if (1 == pwfex- nChannels) { StringCbPrintfA(buffer, sizeof(buffer), "%d channel, %2.1fkHz, %d-bit", (int)pwfex- nChannels, (float)pwfex- nSamplesPerSec / 1000, (int)pwfex- wBitsPerSample); } else { StringCbPrintfA(buffer, sizeof(buffer), "%d channels, %2.1fkHz, %d-bit", (int)pwfex- nChannels, (float)pwfex- nSamplesPerSec / 1000, (int)pwfex- wBitsPerSample); } // add the item description to combo box int n = m_audioFormatCtrl.AddString(buffer); // store media type pointer in item s data section m_audioFormatCtrl.SetItemData(n, (DWORD_PTR)pmt); // set default format if ((pwfex- wFormatTag == m_wfexDefault.wFormatTag) (pwfex- nChannels == m_wfexDefault.nChannels) (pwfex- nSamplesPerSec == m_wfexDefault.nSamplesPerSec) (pwfex- nAvgBytesPerSec == m_wfexDefault.nAvgBytesPerSec)) { m_audioFormatCtrl.SetCurSel(n); pISC- SetFormat(pmt); } } } } else { m_audioFormatCtrl.AddString("ERROR Unable to retrieve audio formats"); } } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // PopulateCompressionControl // Fill compression control with a selection of video compressors, locate the // encoders and add them to the combo box if they exist. HRESULT CDecklinkCaptureDlg PopulateCompressionControl() { int n = m_compressionCtrl.AddString("Uncompressed"); m_compressionCtrl.SetItemData(n, (DWORD_PTR)ENC_NONE); // search for the DV encoder, MPEG encoder and WM encoder IBaseFilter* pFilter = NULL; HRESULT hr = CoCreateInstance(CLSID_DVVideoEnc, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast void** ( pFilter)); if (SUCCEEDED(hr)) { n = m_compressionCtrl.SetCurSel(m_compressionCtrl.AddString("DV Video Encoder")); m_compressionCtrl.SetItemData(n, (DWORD_PTR)ENC_DV); SAFE_RELEASE(pFilter); } hr = CoCreateInstance(CLSID_WMAsfWriter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast void** ( pFilter)); if (SUCCEEDED(hr)) { n = m_compressionCtrl.SetCurSel(m_compressionCtrl.AddString("Windows Media Encoder")); m_compressionCtrl.SetItemData(n, (DWORD_PTR)ENC_WM); SAFE_RELEASE(pFilter); } m_compressionCtrl.SetCurSel(m_compressor); return S_OK; } //----------------------------------------------------------------------------- // OnCbnSelchangeComboVideodevice // Rebuild graph with selected capture device void CDecklinkCaptureDlg OnCbnSelchangeComboVideodevice() { SAFE_RELEASE(m_pVideoCapture);// release our outstanding reference // remove intermediate filters, since the device selection has changed the capture device will also be removed HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // rebuild graph with new capture device selection PWSTR pName = (PWSTR)m_videoDeviceCtrl.GetItemData(m_videoDeviceCtrl.GetCurSel()); if (pName) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_VideoInputDeviceCategory, pName, m_pVideoCapture); if (SUCCEEDED(hr)) { // as the device has changed get the current operating format so that the control // and display this as the current selection CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pVideoCapture, MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // get the current format of the device to set the current selection of the control AM_MEDIA_TYPE* pamt = NULL; hr = pISC- GetFormat( pamt); if (SUCCEEDED(hr)) { if (pamt- pbFormat) { m_vihDefault = *(VIDEOINFOHEADER*)pamt- pbFormat; } DeleteMediaType(pamt); } } hr = PopulateVideoControl();// repopulate the control with formats from the new device if (SUCCEEDED(hr)) { hr = CreatePreviewGraph();// rebuild the graph with the new device } } } else { hr = E_POINTER; } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboAudiodevice // Rebuild graph with selected capture device void CDecklinkCaptureDlg OnCbnSelchangeComboAudiodevice() { SAFE_RELEASE(m_pAudioCapture);// release our outstanding reference // remove intermediate filters, since the device selection has changed the capture device will also be removed HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { PWSTR pName = (PWSTR)m_audioDeviceCtrl.GetItemData(m_audioDeviceCtrl.GetCurSel()); if (pName) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_AudioInputDeviceCategory, pName, m_pAudioCapture); if (SUCCEEDED(hr)) { // as the device has changed get the current operating format so that the control // and display this as the current selection CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pAudioCapture, MEDIATYPE_Audio, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // get the current format of the device to set the current selection of the control AM_MEDIA_TYPE* pamt = NULL; hr = pISC- GetFormat( pamt); if (SUCCEEDED(hr)) { if (pamt- pbFormat) { m_wfexDefault = *(WAVEFORMATEX*)pamt- pbFormat; } DeleteMediaType(pamt); } } hr = PopulateAudioControl();// repopulate the control with formats from the new device if (SUCCEEDED(hr)) { hr = CreatePreviewGraph();// rebuild the graph with the new device } } } else { hr = E_POINTER; } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboVideoformats // Rebuild preview graph if format selection changed void CDecklinkCaptureDlg OnCbnSelchangeComboVideoformats() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // locate the video capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pVideoCapture, MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // set the new media format AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(m_videoFormatCtrl.GetCurSel()); m_vihDefault = *(VIDEOINFOHEADER*)pmt- pbFormat; ASSERT(sizeof(VIDEOINFOHEADER) = pmt- cbFormat); hr = pISC- SetFormat(pmt); if (SUCCEEDED(hr)) { // save the new format EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoFormat", reinterpret_cast const BYTE* ( m_vihDefault), sizeof(m_vihDefault))); // update compression control, we don t have an HD compression filter so disable compression for HD formats if (576 m_vihDefault.bmiHeader.biHeight) { m_compressor = 0; m_compressionCtrl.SetCurSel(m_compressor); // save the new state EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoCompressor", reinterpret_cast const BYTE* ( m_compressor), sizeof(m_compressor))); m_bEnableCompressionCtrl = FALSE; } else { m_bEnableCompressionCtrl = TRUE; } EnableControls(); // rebuild the graph hr = CreatePreviewGraph(); } } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboAudioformats // Rebuild preview graph if format selection changed void CDecklinkCaptureDlg OnCbnSelchangeComboAudioformats() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // locate the audio capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pAudioCapture, MEDIATYPE_Audio, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // set the new media format AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)m_audioFormatCtrl.GetItemData(m_audioFormatCtrl.GetCurSel()); m_wfexDefault = *(WAVEFORMATEX*)pmt- pbFormat; ASSERT(sizeof(WAVEFORMATEX) == pmt- cbFormat); hr = pISC- SetFormat(pmt); if (SUCCEEDED(hr)) { // save the new format EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioFormat", reinterpret_cast const BYTE* ( m_wfexDefault), sizeof(m_wfexDefault))); // rebuild the graph hr = CreatePreviewGraph(); } } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboCompression // Rebuild preview graph if compression selection changed void CDecklinkCaptureDlg OnCbnSelchangeComboCompression() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // save the new state m_compressor = m_compressionCtrl.GetCurSel(); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoCompressor", reinterpret_cast const BYTE* ( m_compressor), sizeof(m_compressor))); // rebuild the graph hr = CreatePreviewGraph(); } } //----------------------------------------------------------------------------- // OnBnClickedCheckAudiomute // Rebuild the capture graph to reflect the new audio setting void CDecklinkCaptureDlg OnBnClickedCheckAudiomute() { CButton* pCheck = (CButton*)GetDlgItem(IDC_CHECK_AUDIOMUTE); if (pCheck) { m_bAudioMute = pCheck- GetState() 0x0003; HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // save the new state EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioMute", reinterpret_cast const BYTE* ( m_bAudioMute), sizeof(m_bAudioMute))); // rebuild the graph which reflects the new audio setting hr = CreatePreviewGraph(); } } } //----------------------------------------------------------------------------- // OnBnClickedButtonBrowse // Create a file open dialog to browse for a file location void CDecklinkCaptureDlg OnBnClickedButtonBrowse() { char BASED_CODE szFilters[] = "Windows Media Files|*.avi;*.asf;*.wmv|All Files (*.*)|*.*||"; char* pExt[] = {"*.avi", "*.avi", "*.asf;*.wmv"}; CFileDialog FileDlg(TRUE, "Windows Media Files", pExt[m_compressor], 0, szFilters, this); if (FileDlg.DoModal() == IDOK) { m_captureFile = FileDlg.GetPathName(); m_captureFileCtrl.SetWindowText(m_captureFile); } } //----------------------------------------------------------------------------- // OnBnClickedButtonCapture // Create a capture graph a start capture void CDecklinkCaptureDlg OnBnClickedButtonCapture() { HRESULT hr = CreateCaptureGraph(); if (SUCCEEDED(hr)) { if (m_pControl) { hr = m_pControl- Run(); if (SUCCEEDED(hr)) { DisableControls(); } } } } //----------------------------------------------------------------------------- // OnBnClickedButtonStop // Stop capture and revert to preview void CDecklinkCaptureDlg OnBnClickedButtonStop() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { hr = CreatePreviewGraph(); if (SUCCEEDED(hr)) { EnableControls(); } } } //----------------------------------------------------------------------------- // EnableControls // void CDecklinkCaptureDlg EnableControls(void) { CWnd* pWnd = GetDlgItem(IDC_COMBO_VIDEOFORMATS); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_COMBO_AUDIOFORMATS); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_CHECK_AUDIOMUTE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_COMBO_COMPRESSION); m_bEnableCompressionCtrl = (576 m_vihDefault.bmiHeader.biHeight) ? FALSE TRUE;// don t have an HDV codec do disable compression control for HD formats pWnd- EnableWindow(m_bEnableCompressionCtrl); pWnd = GetDlgItem(IDC_EDIT_CAPTUREFILE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_BUTTON_BROWSE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_BUTTON_CAPTURE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_BUTTON_STOP); pWnd- EnableWindow(FALSE); } //----------------------------------------------------------------------------- // DisableControls // void CDecklinkCaptureDlg DisableControls(void) { CWnd* pWnd = GetDlgItem(IDC_COMBO_VIDEOFORMATS); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_COMBO_AUDIOFORMATS); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_CHECK_AUDIOMUTE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_COMBO_COMPRESSION); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_EDIT_CAPTUREFILE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_BUTTON_BROWSE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_BUTTON_CAPTURE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_BUTTON_STOP); pWnd- EnableWindow(TRUE); } //----------------------------------------------------------------------------- // QueryRegistry // retrieve previous media formats from registry void CDecklinkCaptureDlg QueryRegistry(void) { if (ERROR_SUCCESS == m_regUtils.Open("DecklinkCaptureSample")) { EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("VideoFormat", reinterpret_cast LPBYTE ( m_vihDefault), sizeof(m_vihDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("AudioFormat", reinterpret_cast LPBYTE ( m_wfexDefault), sizeof(m_wfexDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("AudioMute", reinterpret_cast LPBYTE ( m_bAudioMute), sizeof(m_bAudioMute))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("VideoCompressor", reinterpret_cast LPBYTE ( m_compressor), sizeof(m_compressor))); WCHAR captureFile[MAX_PATH]; ZeroMemory(captureFile, sizeof(captureFile)); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetString("CaptureFile", reinterpret_cast LPBYTE (captureFile), sizeof(captureFile))); m_captureFile = captureFile; } else { // create the key and registry values if (ERROR_SUCCESS == m_regUtils.Create("DecklinkCaptureSample")) { EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoFormat", reinterpret_cast const BYTE* ( m_vihDefault), sizeof(m_vihDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioFormat", reinterpret_cast const BYTE* ( m_wfexDefault), sizeof(m_wfexDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioMute", reinterpret_cast const BYTE* ( m_bAudioMute), sizeof(m_bAudioMute))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoCompressor", reinterpret_cast const BYTE* ( m_compressor), sizeof(m_compressor))); } } // update mute audio check box control CButton* pButton = (CButton*)GetDlgItem(IDC_CHECK_AUDIOMUTE); pButton- SetCheck(m_bAudioMute); }
https://w.atwiki.jp/bmd_intensity/pages/26.html
//----------------------------------------------------------------------------- // $Id DecklinkCaptureDlg.cpp,v 1.9 2006/04/11 01 11 07 ivanr Exp $ // // Desc DirectShow capture sample // // Copyright (c) Blackmagic Design 2005. All rights reserved. //----------------------------------------------------------------------------- #include "stdafx.h" #include "DecklinkCapture.h" #include "DecklinkCaptureDlg.h" #include initguid.h // TODO move this to a lib #include "DecklinkSample_uuids.h" #undef lstrlenW #ifdef _DEBUG #define new DEBUG_NEW #endif #define WM_GRAPHNOTIFYWM_APP+1// for Filter Graph event notification //----------------------------------------------------------------------------- // CAboutDlg //----------------------------------------------------------------------------- // CAboutDlg dialog used for App About class CAboutDlg public CDialog { public CAboutDlg(); // Dialog Data enum { IDD = IDD_ABOUTBOX }; protected virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected DECLARE_MESSAGE_MAP() }; CAboutDlg CAboutDlg() CDialog(CAboutDlg IDD) { } void CAboutDlg DoDataExchange(CDataExchange* pDX) { CDialog DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() //----------------------------------------------------------------------------- // CDecklinkCaptureDlg dialog //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Constructor // CDecklinkCaptureDlg CDecklinkCaptureDlg(CWnd* pParent /*=NULL*/) CDialog(CDecklinkCaptureDlg IDD, pParent) , m_pIVW(NULL) { m_hIcon = AfxGetApp()- LoadIcon(IDR_MAINFRAME); } //----------------------------------------------------------------------------- // DoDataExchange // void CDecklinkCaptureDlg DoDataExchange(CDataExchange* pDX) { CDialog DoDataExchange(pDX); DDX_Control(pDX, IDC_COMBO_VIDEOFORMATS, m_videoFormatCtrl); DDX_Control(pDX, IDC_COMBO_AUDIOFORMATS, m_audioFormatCtrl); DDX_Control(pDX, IDC_STATIC_PREVIEW, m_preview); DDX_Control(pDX, IDC_EDIT_CAPTUREFILE, m_captureFileCtrl); DDX_Control(pDX, IDC_COMBO_COMPRESSION, m_compressionCtrl); DDX_Control(pDX, IDC_COMBO_VIDEODEVICE, m_videoDeviceCtrl); DDX_Control(pDX, IDC_COMBO_AUDIODEVICE, m_audioDeviceCtrl); } BEGIN_MESSAGE_MAP(CDecklinkCaptureDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_CBN_SELCHANGE(IDC_COMBO_VIDEOFORMATS, OnCbnSelchangeComboVideoformats) ON_CBN_SELCHANGE(IDC_COMBO_AUDIOFORMATS, OnCbnSelchangeComboAudioformats) ON_BN_CLICKED(IDC_CHECK_AUDIOMUTE, OnBnClickedCheckAudiomute) ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnBnClickedButtonBrowse) ON_BN_CLICKED(IDC_BUTTON_CAPTURE, OnBnClickedButtonCapture) ON_BN_CLICKED(IDC_BUTTON_STOP, OnBnClickedButtonStop) ON_CBN_SELCHANGE(IDC_COMBO_COMPRESSION, OnCbnSelchangeComboCompression) ON_CBN_SELCHANGE(IDC_COMBO_VIDEODEVICE, OnCbnSelchangeComboVideodevice) ON_CBN_SELCHANGE(IDC_COMBO_AUDIODEVICE, OnCbnSelchangeComboAudiodevice) END_MESSAGE_MAP() //----------------------------------------------------------------------------- // CDecklinkCaptureDlg message handlers //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // OnInitDialog // Called before the dialog is displayed, use this message handler to initialise // our app BOOL CDecklinkCaptureDlg OnInitDialog() { CDialog OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu- AppendMenu(MF_SEPARATOR); pSysMenu- AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application s main window is not a dialog SetIcon(m_hIcon, TRUE);// Set big icon SetIcon(m_hIcon, FALSE);// Set small icon // create a basic capture graph and preview the incoming video m_pGraph = NULL; m_pVideoCapture = NULL; m_pAudioCapture = NULL; m_pVideoRenderer = NULL; m_pSmartT = NULL; m_pControl = NULL; m_pIVW = NULL; m_pMediaEvent = NULL; m_ROTRegister = 0; m_bAudioMute = FALSE; m_compressor = 0; m_bEnableCompressionCtrl = TRUE; m_captureFile = " Select File "; // initialise default video media type ZeroMemory( m_vihDefault, sizeof(m_vihDefault)); m_vihDefault.AvgTimePerFrame = 333667; m_vihDefault.bmiHeader.biWidth = 720; m_vihDefault.bmiHeader.biHeight = 486; m_vihDefault.bmiHeader.biBitCount = 16; m_vihDefault.bmiHeader.biCompression = YVYU ; // initialise default audio media type ZeroMemory( m_wfexDefault, sizeof(m_wfexDefault)); m_wfexDefault.nChannels = 2;// the only field of interest // retrieve last state QueryRegistry(); m_captureFileCtrl.SetWindowText(m_captureFile); EnableControls(); // create a preview graph // add the filters that will be used by all the graphs; preview, uncompressed capture, dv capture, // mpeg capture and windows media capture HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, reinterpret_cast void** ( m_pGraph)); if (SUCCEEDED(hr)) { #ifdef _DEBUG hr = CDSUtils AddGraphToRot(m_pGraph, m_ROTRegister); #endif hr = m_pGraph- QueryInterface(IID_IMediaControl, reinterpret_cast void** ( m_pControl)); if (SUCCEEDED(hr)) { // locate the video capture devices hr = PopulateDeviceControl( CLSID_VideoInputDeviceCategory, m_videoDeviceCtrl); if (SUCCEEDED(hr)) { hr = PopulateDeviceControl( CLSID_AudioInputDeviceCategory, m_audioDeviceCtrl); if (SUCCEEDED(hr)) { PWSTR pVideoName = (PWSTR)m_videoDeviceCtrl.GetItemData(m_videoDeviceCtrl.SetCurSel(0)); PWSTR pAudioName = (PWSTR)m_audioDeviceCtrl.GetItemData(m_audioDeviceCtrl.SetCurSel(0)); if (pVideoName pAudioName) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_VideoInputDeviceCategory, pVideoName, m_pVideoCapture); if (SUCCEEDED(hr)) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_AudioInputDeviceCategory, pAudioName, m_pAudioCapture); if (SUCCEEDED(hr)) { PopulateVideoControl();// populate the video format control with the video formats of the currently selected device PopulateAudioControl();// populate the audio format control with the audio formats of the currently selected device PopulateCompressionControl(); // locate video screen renderer for the preview window hr = CDSUtils AddFilter(m_pGraph, CLSID_VideoRendererDefault, L"Video Renderer", m_pVideoRenderer); if (SUCCEEDED(hr)) { hr = CreatePreviewGraph(); } } } } } } } } return TRUE; // return TRUE unless you set the focus to a control } //----------------------------------------------------------------------------- // DestroyWindow // Called when the window is being destroyed, clean up and free all resources. BOOL CDecklinkCaptureDlg DestroyWindow() { m_regUtils.Close(); #ifdef _DEBUG CDSUtils RemoveGraphFromRot(m_ROTRegister); #endif DestroyGraph(); SAFE_RELEASE(m_pControl); // Hide Video Window and remove owner. This has to be done prior to // destroying any window that displays video/still. if (m_pIVW) { m_pIVW- put_Visible(OAFALSE); m_pIVW- put_Owner(NULL); } SAFE_RELEASE(m_pIVW); SAFE_RELEASE(m_pMediaEvent); SAFE_RELEASE(m_pVideoRenderer); SAFE_RELEASE(m_pAudioCapture); SAFE_RELEASE(m_pVideoCapture); SAFE_RELEASE(m_pGraph); // free mediatypes attached to format controls int count = m_videoFormatCtrl.GetCount(); for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(item)); } count = m_audioFormatCtrl.GetCount(); for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_audioFormatCtrl.GetItemData(item)); } // release the device names attached to the item s data count = m_videoDeviceCtrl.GetCount(); for (item=0; item count; ++item) { PWSTR pName = (PWSTR)m_videoDeviceCtrl.GetItemData(item); delete [] pName; } count = m_audioDeviceCtrl.GetCount(); for (item=0; item count; ++item) { PWSTR pName = (PWSTR)m_audioDeviceCtrl.GetItemData(item); delete [] pName; } return CDialog DestroyWindow(); } //----------------------------------------------------------------------------- // OnSysCommand // void CDecklinkCaptureDlg OnSysCommand(UINT nID, LPARAM lParam) { if ((nID 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog OnSysCommand(nID, lParam); } } //----------------------------------------------------------------------------- // OnPaint // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CDecklinkCaptureDlg OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast WPARAM (dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect( rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog OnPaint(); } } //----------------------------------------------------------------------------- // HandleGraphEvent // At the moment we just read the event, discard it and release memory used to store it. void CDecklinkCaptureDlg HandleGraphEvent(void) { LONG lEventCode, lEventParam1, lEventParam2; if (!m_pMediaEvent) { return; } while (SUCCEEDED(m_pMediaEvent- GetEvent( lEventCode, reinterpret_cast LONG_PTR * ( lEventParam1), reinterpret_cast LONG_PTR * ( lEventParam2), 0))) { // just free memory associated with event m_pMediaEvent- FreeEventParams(lEventCode, lEventParam1, lEventParam2); } } //----------------------------------------------------------------------------- // WindowProc // Have to add our own message handling loop to handle events from the preview video // window and to pass Window events onto it - this is so it redraws itself correctly etc. LRESULT CDecklinkCaptureDlg WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_GRAPHNOTIFY HandleGraphEvent(); break; } // Pass all msgs to video window. vid window exists as child of static // picture frame. This ensures video window redraws itself etc. if (m_pIVW) { m_pIVW- NotifyOwnerMessage(reinterpret_cast LONG_PTR (m_hWnd) /* from me */, message, wParam, lParam); } return CDialog WindowProc(message, wParam, lParam); } //----------------------------------------------------------------------------- // OnQueryDragIcon // The system calls this function to obtain the cursor to display while the user drags // the minimized window. HCURSOR CDecklinkCaptureDlg OnQueryDragIcon() { return static_cast HCURSOR (m_hIcon); } //----------------------------------------------------------------------------- // CreatePreviewGraph // Create a graph to preview the input // NOTE There are many ways of building graphs, you could opt for the ICaptureGraphBuilder interface which would // make things are lot simpler, however it doesn t always build the most efficient graphs. HRESULT CDecklinkCaptureDlg CreatePreviewGraph() { HRESULT hr = S_OK; if (m_pGraph) { // locate smart-T // NOTE The smart-T appears to hold references to its upstream connections even when its input pin // is diconnected. The smart-T has to be removed from the graph in order to clear these references which // is why the filter is enumerated and added every time the preview graph is built and removed whenever // it is destroyed. ASSERT(NULL == m_pSmartT); hr = CDSUtils AddFilter(m_pGraph, CLSID_SmartTee, L"Smart Tee", m_pSmartT); if (SUCCEEDED(hr)) { // DV preview is slightly different to all other previews if (ENC_DV != m_compressionCtrl.GetItemData(m_compressionCtrl.GetCurSel())) { // uncompressed, mpeg and wm preview // create the following // // Decklink Video Capture - Smart-T - AVI Decompressor - Video Renderer // Decklink Audio Capture - Default Audio Renderer // // render the preview pin on the smart-T filter // first connect the Decklink video capture pin to the smart-T hr = CDSUtils ConnectFilters(m_pGraph, m_pVideoCapture, NULL, m_pSmartT, NULL); if (SUCCEEDED(hr)) { // now connect the preview pin of the smart-T to the video renderer hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Preview", m_pVideoRenderer, NULL); } } else { // DV Preview // create the following // // Decklink Video Capture - AVI Decompressor - Smart-T - Colour Space Converter - Video Renderer // Decklink Audio Capture - Default Audio Renderer // // this is a more efficient graph than created by the ICaptureGraphBuilder2 interface // add the AVI decompressor and colour space converter filters CComPtr IBaseFilter pAVIDecompressor = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_AVIDec, L"AVI Decompressor", pAVIDecompressor); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pColourSpaceConverter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_Colour, L"Color Space Converter", pColourSpaceConverter); if (SUCCEEDED(hr)) { // conect the Decklink video capture pin to the AVI decompressor hr = CDSUtils ConnectFilters(m_pGraph, m_pVideoCapture, NULL, pAVIDecompressor, NULL); if (SUCCEEDED(hr)) { // connect AVI decompressor to the smart-T hr = CDSUtils ConnectFilters(m_pGraph, pAVIDecompressor, NULL, m_pSmartT, NULL); if (SUCCEEDED(hr)) { // connect the preview pin of the smart-T to the colour space converter hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Preview", pColourSpaceConverter, NULL); if (SUCCEEDED(hr)) { // connect the colour space converter to the video renderer hr = CDSUtils ConnectFilters(m_pGraph, pColourSpaceConverter, NULL, m_pVideoRenderer, NULL); } } } } } } } } else { hr = E_POINTER; } if (SUCCEEDED(hr)) { // the video path has been connected, initialise the preview window InitialiseVideoPreview(); // optionally connect the audio path if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the mux hr = CDSUtils RenderFilter(m_pGraph, m_pAudioCapture, L"Capture"); } // run the graph so that we can preview the input video if (m_pControl) { hr = m_pControl- Run(); } else { hr = E_POINTER; } } return hr; } //----------------------------------------------------------------------------- // CreateCaptureGraph // Create a graph to capture the input HRESULT CDecklinkCaptureDlg CreateCaptureGraph() { HRESULT hr = S_OK; // tack the file writer onto the preview graph if (m_pGraph m_pControl) { // stop the graph as we are about to modify it m_pControl- Stop(); // remove the default audio renderer so the Decklink audio capture filter // can be connected to the AVI mux, we will not preview audio whilst capturing CComPtr IPin pIPinOutput = NULL; hr = CDSUtils GetPin(m_pAudioCapture, L"Capture", pIPinOutput); if (SUCCEEDED(hr)) { // to disconnect both pins must be disconnected // find the pin connected to the Decklink audio capture pin CComPtr IPin pIPinConnection = NULL; hr = pIPinOutput- ConnectedTo( pIPinConnection); if (SUCCEEDED(hr)) { // disconnect the pins hr = m_pGraph- Disconnect(pIPinOutput); hr = m_pGraph- Disconnect(pIPinConnection); // get the owning filter of the downstream pin and remove it from the graph PIN_INFO pinInfo = {0}; hr = pIPinConnection- QueryPinInfo( pinInfo); if (SUCCEEDED(hr)) { if (pinInfo.pFilter) { hr = m_pGraph- RemoveFilter(pinInfo.pFilter); pinInfo.pFilter- Release(); } } } } // retrieve the capture filename m_captureFileCtrl.GetWindowText(m_captureFile); // store filename USES_CONVERSION; WCHAR captureFile[MAX_PATH]; wcsncpy(captureFile, A2W(m_captureFile), MAX_PATH); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetString("CaptureFile", reinterpret_cast const BYTE* (captureFile), sizeof(captureFile))); // decide the type of capture graph to build switch (m_compressionCtrl.GetItemData(m_compressionCtrl.GetCurSel())) { default case ENC_NONE hr = CreateUncompressedCaptureGraph(); break; case ENC_DV hr = CreateDVCaptureGraph(); break; case ENC_WM hr = CreateWMCaptureGraph(); break; } if (FAILED(hr)) { // there was a problem building the capture graph, issue a message // and rebuild preview graph char buffer[128]; StringCbPrintfA(buffer, sizeof(buffer), "The error 0x%08lx was detected when creating the capture graph with the following file name \r\n\r\n %s ", hr, m_captureFile); MessageBox(buffer, _T("Error"), MB_ICONERROR); OnBnClickedButtonStop();// destroy broken capture graph, build preview graph and enable controls } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // CreateUncompressedCaptureGraph // Create an optimum uncompressed capture graph HRESULT CDecklinkCaptureDlg CreateUncompressedCaptureGraph() { HRESULT hr = S_OK; // uncompressed capture // locate the AVI mux and file writer filters and add them to the graph CComPtr IBaseFilter pAVIMux = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_AviDest , L"AVI Mux", pAVIMux); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pFileWriter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_FileWriter, L"File writer", pFileWriter); if (SUCCEEDED(hr)) { // set the output filename CComQIPtr IFileSinkFilter, IID_IFileSinkFilter pIFS = pFileWriter; if (pIFS) { USES_CONVERSION;// for T2W macro hr = pIFS- SetFileName(T2W(m_captureFile), NULL); if (SUCCEEDED(hr)) { // connect the smart-T capture pin to the mux hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Capture", pAVIMux, NULL); if (SUCCEEDED(hr)) { // connect the mux to the file writer hr = CDSUtils ConnectFilters(m_pGraph, pAVIMux, NULL, pFileWriter, NULL); if (SUCCEEDED(hr)) { // video path connected now optionally connect the audio path if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the mux hr = CDSUtils ConnectFilters(m_pGraph, m_pAudioCapture, L"Capture", pAVIMux, NULL); } if (SUCCEEDED(hr)) { m_pControl- Run(); } } } } } } } return hr; } //----------------------------------------------------------------------------- // CreateDVCaptureGraph // Create an optimum DV capture graph // NOTE that this will only work for SD HRESULT CDecklinkCaptureDlg CreateDVCaptureGraph() { HRESULT hr = S_OK; // locate the DV encoder, AVI mux and file writer filters and add them to the graph CComPtr IBaseFilter pDVEncoder = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_DVVideoEnc, L"DV Video Encoder", pDVEncoder); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pAVIMux = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_AviDest , L"AVI Mux", pAVIMux); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pFileWriter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_FileWriter, L"File writer", pFileWriter); if (SUCCEEDED(hr)) { // set the output filename CComQIPtr IFileSinkFilter, IID_IFileSinkFilter pIFS = pFileWriter; if (pIFS) { USES_CONVERSION;// for T2W macro hr = pIFS- SetFileName(T2W(m_captureFile), NULL); if (SUCCEEDED(hr)) { // configure the DV encoder CComQIPtr IDVEnc, IID_IDVEnc pIDV = pDVEncoder; if (pIDV) { // located a DV compression filter, set the format int videoFormat, dvFormat, resolution; hr = pIDV- get_IFormatResolution( videoFormat, dvFormat, resolution, FALSE, NULL); if (SUCCEEDED(hr)) { ASSERT(DVENCODERFORMAT_DVSD == dvFormat); ASSERT(DVENCODERRESOLUTION_720x480 == resolution); if ((DVENCODERVIDEOFORMAT_NTSC == videoFormat) (576 == m_vihDefault.bmiHeader.biHeight)) { // set the encoder to PAL if its NTSC videoFormat = DVENCODERVIDEOFORMAT_PAL; hr = pIDV- put_IFormatResolution(videoFormat, dvFormat, resolution, FALSE, NULL); } else if ((DVENCODERVIDEOFORMAT_PAL == videoFormat) (486 == m_vihDefault.bmiHeader.biHeight)) { // set the encoder to NTSC if its PAL videoFormat = DVENCODERVIDEOFORMAT_NTSC; hr = pIDV- put_IFormatResolution(videoFormat, dvFormat, resolution, FALSE, NULL); } } } if (SUCCEEDED(hr)) { // if the format is PAL, insert the Decklink field swap filter, PAL DV is the opposite // field order to PAL SD if (576 == m_vihDefault.bmiHeader.biHeight) { CComPtr IBaseFilter pPALFieldSwap = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_DecklinkFieldSwap, L"Decklink PAL Field Swap", pPALFieldSwap); if (SUCCEEDED(hr)) { // connect the smart-T capture pin to the PAL field swap filter hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Capture", pPALFieldSwap, NULL); if (SUCCEEDED(hr)) { // connect the field swap filter to the DV encoder hr = CDSUtils ConnectFilters(m_pGraph, pPALFieldSwap, NULL, pDVEncoder, NULL); } } } else { // connect the smart-T capture pin to the DV Encoder hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Capture", pDVEncoder, NULL); } if (SUCCEEDED(hr)) { // connect the DV encoder output to the AVI mux hr = CDSUtils ConnectFilters(m_pGraph, pDVEncoder, NULL, pAVIMux, NULL); if (SUCCEEDED(hr)) { // connect the mux to the file writer hr = CDSUtils ConnectFilters(m_pGraph, pAVIMux, NULL, pFileWriter, NULL); if (SUCCEEDED(hr)) { // video path connected now optionally connect the audio path if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the mux hr = CDSUtils ConnectFilters(m_pGraph, m_pAudioCapture, L"Capture", pAVIMux, NULL); } if (SUCCEEDED(hr)) { m_pControl- Run(); } } } } } } } } } } return hr; } //----------------------------------------------------------------------------- // CreateWMCaptureGraph // Create an optimum Windows Media capture graph HRESULT CDecklinkCaptureDlg CreateWMCaptureGraph() { HRESULT hr = S_OK; // locate the asf writer filter and add it to the graph CComPtr IBaseFilter pASFWriter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_WMAsfWriter, L"WM ASF Writer", pASFWriter); if (SUCCEEDED(hr)) { // set the output filename CComQIPtr IFileSinkFilter, IID_IFileSinkFilter pIFS = pASFWriter; if (pIFS) { USES_CONVERSION;// for T2W macro hr = pIFS- SetFileName(T2W(m_captureFile), NULL); if (SUCCEEDED(hr)) { hr = ConfigureWMEncoder(pASFWriter); } } if (SUCCEEDED(hr)) { if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the ASF writer hr = CDSUtils ConnectFilters(m_pGraph, m_pAudioCapture, pASFWriter, MEDIATYPE_Audio); } if (SUCCEEDED(hr)) { // connect the smart-T capture pin to the ASF writer hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, pASFWriter, MEDIATYPE_Video); if (SUCCEEDED(hr)) { m_pControl- Run(); } } } } return hr; } //----------------------------------------------------------------------------- // ConfigureWMEncoder // Configure the Windows Media encoder HRESULT CDecklinkCaptureDlg ConfigureWMEncoder(IBaseFilter* pASFWriter) { HRESULT hr = S_OK; // modify the video output resolution of a system profile if (pASFWriter) { // simple system profile encoding CComQIPtr IConfigAsfWriter, IID_IConfigAsfWriter pICW = pASFWriter; if (pICW) { //NOTE You could just use the following for a default system profile //hr = pICW- ConfigureFilterUsingProfileGuid(WMProfile_XXX);// RE wmsysprf.h //NOTE If you want video only capture you must modify the profile to remove the audio // otherwise encoding will fail // Load a system profile and modify the resolution of the video output // NOTE The scope of the encoding is enormous, this just demonstrates how to change // the output video resolution from 320x240 to something larger. // Changing the resolution affects coding performance, it is likely that the encoder will // start to drop frames after a while. Using WM9 codecs will probably improve performance // and that has been left to the reader... ;o) // // get a profile manager CComPtr IWMProfileManager pIWMProfileManager = NULL; hr = WMCreateProfileManager( pIWMProfileManager); if (SUCCEEDED(hr)) { // load a system profile to modify CComPtr IWMProfile pIWMProfile = NULL; // NOTE Any WMProfile_XXX could be used here, or create a custom profile from scratch hr = pIWMProfileManager- LoadProfileByID(WMProfile_V80_FAIRVBRVideo, pIWMProfile); if (SUCCEEDED(hr)) { // search the streams for the video stream and attempt to modify the video size DWORD cbStreams = 0; hr = pIWMProfile- GetStreamCount( cbStreams); if (SUCCEEDED(hr)) { IWMStreamConfig* pIWMStreamConfig = NULL; GUID streamType = {0}; DWORD stream; if (m_bAudioMute) { // remove the audio stream for video only capture for (stream=0; stream cbStreams; ++stream) { hr = pIWMProfile- GetStream(stream, pIWMStreamConfig); if (SUCCEEDED(hr)) { hr = pIWMStreamConfig- GetStreamType( streamType); if (SUCCEEDED(hr)) { if (MEDIATYPE_Audio == streamType) { if (SUCCEEDED(pIWMProfile- RemoveStream(pIWMStreamConfig))) { --cbStreams; } SAFE_RELEASE(pIWMStreamConfig); break; } } } } } for (stream=0; stream cbStreams; ++stream) { hr = pIWMProfile- GetStream(stream, pIWMStreamConfig); if (SUCCEEDED(hr)) { hr = pIWMStreamConfig- GetStreamType( streamType); if (SUCCEEDED(hr) (MEDIATYPE_Video == streamType)) { // found the video stream CComQIPtr IWMMediaProps, IID_IWMMediaProps pIWMMediaProps = pIWMStreamConfig; if (pIWMMediaProps) { // get the size of the media type WM_MEDIA_TYPE* pMediaType = NULL; DWORD cbMediaType = 0; hr = pIWMMediaProps- GetMediaType(pMediaType, cbMediaType); if (SUCCEEDED(hr)) { pMediaType = (WM_MEDIA_TYPE*)new char [cbMediaType]; if (pMediaType) { hr = pIWMMediaProps- GetMediaType(pMediaType, cbMediaType); if (SUCCEEDED(hr)) { BITMAPINFOHEADER* pbmih = NULL; if (WMFORMAT_VideoInfo == pMediaType- formattype) { WMVIDEOINFOHEADER* pvih = (WMVIDEOINFOHEADER*)pMediaType- pbFormat; pbmih = pvih- bmiHeader; } else if (WMFORMAT_MPEG2Video == pMediaType- formattype) { WMVIDEOINFOHEADER2* pvih = (WMVIDEOINFOHEADER2*) ((WMMPEG2VIDEOINFO*)pMediaType- pbFormat)- hdr; pbmih = pvih- bmiHeader; } if (pbmih) { // modify the video dimensions, set the property, reconfigure the stream // and then configure the ASF writer with this modified profile pbmih- biWidth = 640;// was 320; pbmih- biHeight = 480;// was 240; pbmih- biSizeImage = pbmih- biWidth * pbmih- biHeight * pbmih- biBitCount / 8;// NOTE This calculation is not correct for all bit depths hr = pIWMMediaProps- SetMediaType(pMediaType); if (SUCCEEDED(hr)) { // config the ASF writer filter to use this modified system profile hr = pIWMProfile- ReconfigStream(pIWMStreamConfig); if (SUCCEEDED(hr)) { hr = pICW- ConfigureFilterUsingProfile(pIWMProfile); } } } } delete [] (char*)pMediaType; } } } } SAFE_RELEASE(pIWMStreamConfig); } } } } } /* // modify other ASF writer properties IServiceProvider* pProvider = NULL; hr = pASFWriter- QueryInterface(IID_IServiceProvider, reinterpret_cast void** ( pProvider)); if (SUCCEEDED(hr)) { IID_IWMWriterAdvanced2* pWMWA2 = NULL; hr = pProvider- QueryService(IID_IID_IWMWriterAdvanced2, IID_IID_IWMWriterAdvanced2, reinterpret_cast void** ( pWMWA2)); if (SUCCEEDED(hr)) { // set the deinterlace mode pWMWA2- GetInputSetting(...); SAFE_RELEASE(pWMWA2); } SAFE_RELEASE(pProvider); } */ } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // DestroyGraph // Remove all intermediate filters, keep any Decklink and video render filters as // these are used by all the graphs. HRESULT CDecklinkCaptureDlg DestroyGraph() { HRESULT hr = S_OK; if (m_pGraph m_pControl) { m_pControl- Stop(); // release our outstanding reference on this filter so it can be removed from the graph SAFE_RELEASE(m_pSmartT); // retrieve the name of the capture device, don t remove it in this method PWSTR pNameVideoCapture = (PWSTR)m_videoDeviceCtrl.GetItemData(m_videoDeviceCtrl.GetCurSel()); PWSTR pNameAudioCapture = (PWSTR)m_audioDeviceCtrl.GetItemData(m_audioDeviceCtrl.GetCurSel()); CComPtr IEnumFilters pEnum = NULL; hr = m_pGraph- EnumFilters( pEnum); if (SUCCEEDED(hr)) { IBaseFilter* pFilter = NULL; while (S_OK == pEnum- Next(1, pFilter, NULL)) { FILTER_INFO filterInfo = {0}; hr = pFilter- QueryFilterInfo( filterInfo); if (SUCCEEDED(hr)) { SAFE_RELEASE(filterInfo.pGraph); if ((NULL == wcsstr(filterInfo.achName, pNameVideoCapture)) (NULL == wcsstr(filterInfo.achName, pNameAudioCapture)) (NULL == wcsstr(filterInfo.achName, L"Video Renderer"))) { hr = m_pGraph- RemoveFilter(pFilter); if (SUCCEEDED(hr)) { hr = pEnum- Reset(); } } } SAFE_RELEASE(pFilter); } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // InitialiseVideoPreview // In short get the video screen renderer to draw into the picture control, which is our preview window // the following code sets this up, in addition to adding the HandleGraphEvent and WindowProc methods // read the DXSDK docos for more detailed information void CDecklinkCaptureDlg InitialiseVideoPreview(void) { // modify the preview window if (m_pVideoRenderer) { if (NULL == m_pIVW) { if (SUCCEEDED(m_pVideoRenderer- QueryInterface(IID_IVideoWindow, reinterpret_cast void** ( m_pIVW)))) { // get the window to handle redraws, etc // Set msg drain of VideoWindow to point to our dialog window. The dialog s // window procedure then handles events from the VideoWindow. HRESULT hr = m_pIVW- put_MessageDrain(reinterpret_cast OAHWND (m_hWnd)); if (NULL == m_pMediaEvent) { // Make graph send WM_GRAPHNOTIFY when it wants our attention see "Learning // When an Event Occurs" in the DX9 documentation. hr = m_pGraph- QueryInterface(IID_IMediaEventEx, reinterpret_cast void** ( m_pMediaEvent)); if (SUCCEEDED(hr)) { hr = m_pMediaEvent- SetNotifyWindow(reinterpret_cast OAHWND (m_hWnd), WM_GRAPHNOTIFY, 0); } // object created for it. RECT rc; m_preview.GetClientRect( rc); m_pIVW- SetWindowPosition(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); // VideoWindow is a child window of the bounding rect hr = m_pIVW- put_WindowStyle(WS_CHILD); hr = m_pIVW- put_Owner(reinterpret_cast OAHWND (m_preview.GetSafeHwnd())); hr = m_pIVW- SetWindowForeground(-1); } } } } } //----------------------------------------------------------------------------- // PopulateDeviceControl // Fill device combo box with available devices of the specified category HRESULT CDecklinkCaptureDlg PopulateDeviceControl(const GUID* pCategory, CComboBox* pCtrl) { HRESULT hr = S_OK; if (pCategory pCtrl) { // first enumerate the system devices for the specifed class and filter name CComPtr ICreateDevEnum pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast void** ( pSysDevEnum)); if (SUCCEEDED(hr)) { CComPtr IEnumMoniker pEnumCat = NULL; hr = pSysDevEnum- CreateClassEnumerator(*pCategory, pEnumCat, 0); if (S_OK == hr) { IMoniker* pMoniker = NULL; bool Loop = true; while ((S_OK == pEnumCat- Next(1, pMoniker, NULL)) Loop) { IPropertyBag* pPropBag = NULL; hr = pMoniker- BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast void** ( pPropBag)); if (SUCCEEDED(hr)) { VARIANT varName; VariantInit( varName); hr = pPropBag- Read(L"FriendlyName", varName, 0); if (SUCCEEDED(hr)) { size_t len = wcslen(varName.bstrVal) + 1; PWSTR pName = new WCHAR [len]; StringCchCopyW(pName, len, varName.bstrVal); CW2AEX buf(varName.bstrVal); pCtrl- SetItemData(pCtrl- AddString(buf), (DWORD)pName); } VariantClear( varName); // contained within a loop, decrement the reference count SAFE_RELEASE(pPropBag); } SAFE_RELEASE(pMoniker); } } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // PopulateVideoControl // Fill video format combo box with supported video formats using the IAMStreamConfig // interface. HRESULT CDecklinkCaptureDlg PopulateVideoControl() { HRESULT hr = S_OK; if (m_pVideoCapture) { // free mediatypes attached to format controls int count = m_videoFormatCtrl.GetCount(); if (count) { for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(item)); } m_videoFormatCtrl.ResetContent(); } // locate the video capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pVideoCapture, MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // loop through all the capabilities (video formats) and populate the control int count, size; hr = pISC- GetNumberOfCapabilities( count, size); if (SUCCEEDED(hr)) { if (sizeof(VIDEO_STREAM_CONFIG_CAPS) == size) { AM_MEDIA_TYPE* pmt = NULL; VIDEO_STREAM_CONFIG_CAPS vscc; VIDEOINFOHEADER* pvih = NULL; for (int index=0; index count; ++index) { hr = pISC- GetStreamCaps(index, pmt, reinterpret_cast BYTE* ( vscc)); if (SUCCEEDED(hr)) { char buffer[128]; WORD PixelFormat; float FrameRate; ZeroMemory(buffer, sizeof(buffer)); pvih = (VIDEOINFOHEADER*)pmt- pbFormat; char* pPixelFormatLUT[] = {"4 2 2", "4 4 4"}; if (pvih- bmiHeader.biBitCount == 16) PixelFormat = 8; else if (pvih- bmiHeader.biBitCount == 20) PixelFormat = 10; else PixelFormat = pvih- bmiHeader.biBitCount; // provide a useful description of the formats if (486 == pvih- bmiHeader.biHeight) { if (417083 == pvih- AvgTimePerFrame) { StringCbPrintfA(buffer, sizeof(buffer), "NTSC %d-bit %s (3 2 pulldown removal)", PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "NTSC %d-bit %s", PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else if (576 == pvih- bmiHeader.biHeight) { StringCbPrintfA(buffer, sizeof(buffer), "PAL %d-bit %s", PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { char* pFrameRateFormat[] = {"%.2f", "%.0f"}; FrameRate = (float)(long)UNITS / pvih- AvgTimePerFrame; if ((720 == pvih- bmiHeader.biHeight) (59.94 FrameRate)) { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.2fp %d-bit %s (Overcranked 60p)", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.0fp %d-bit %s (Overcranked 60p)", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else if ((720 == pvih- bmiHeader.biHeight) (59.94 = FrameRate)) { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.2fp %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.0fp %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else if ((1080 == pvih- bmiHeader.biHeight) (50.00 = FrameRate)) { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.2fi %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.0fi %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.2fPsF %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.0fPsF %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } } // add the item description to combo box int n = m_videoFormatCtrl.AddString(buffer); // store media type pointer in item s data section m_videoFormatCtrl.SetItemData(n, (DWORD_PTR)pmt); // set default format if ((pvih- AvgTimePerFrame == m_vihDefault.AvgTimePerFrame) (pvih- bmiHeader.biWidth == m_vihDefault.bmiHeader.biWidth) (pvih- bmiHeader.biHeight == m_vihDefault.bmiHeader.biHeight) (pvih- bmiHeader.biBitCount == m_vihDefault.bmiHeader.biBitCount)) { m_videoFormatCtrl.SetCurSel(n); pISC- SetFormat(pmt); } } } } else { m_videoFormatCtrl.AddString("ERROR Unable to retrieve video formats"); } } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // PopulateAudioControl // Fill audio format combo box with supported audio formats using the IAMStreamConfig // interface. HRESULT CDecklinkCaptureDlg PopulateAudioControl() { HRESULT hr = S_OK; if (m_pAudioCapture) { // free mediatypes attached to format controls int count = m_audioFormatCtrl.GetCount(); if (count) { for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_audioFormatCtrl.GetItemData(item)); } m_audioFormatCtrl.ResetContent(); } // locate the audio capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pAudioCapture, MEDIATYPE_Audio, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // loop through all the capabilities (audio formats) and populate the control int count, size; hr = pISC- GetNumberOfCapabilities( count, size); if (SUCCEEDED(hr)) { if (sizeof(AUDIO_STREAM_CONFIG_CAPS) == size) { AM_MEDIA_TYPE* pmt = NULL; AUDIO_STREAM_CONFIG_CAPS ascc; WAVEFORMATEX* pwfex = NULL; for (int index=0; index count; ++index) { hr = pISC- GetStreamCaps(index, pmt, reinterpret_cast BYTE* ( ascc)); if (SUCCEEDED(hr)) { char buffer[32]; ZeroMemory(buffer, sizeof(buffer)); pwfex = (WAVEFORMATEX*)pmt- pbFormat; // provide a useful description of the formats if (1 == pwfex- nChannels) { StringCbPrintfA(buffer, sizeof(buffer), "%d channel, %2.1fkHz, %d-bit", (int)pwfex- nChannels, (float)pwfex- nSamplesPerSec / 1000, (int)pwfex- wBitsPerSample); } else { StringCbPrintfA(buffer, sizeof(buffer), "%d channels, %2.1fkHz, %d-bit", (int)pwfex- nChannels, (float)pwfex- nSamplesPerSec / 1000, (int)pwfex- wBitsPerSample); } // add the item description to combo box int n = m_audioFormatCtrl.AddString(buffer); // store media type pointer in item s data section m_audioFormatCtrl.SetItemData(n, (DWORD_PTR)pmt); // set default format if ((pwfex- wFormatTag == m_wfexDefault.wFormatTag) (pwfex- nChannels == m_wfexDefault.nChannels) (pwfex- nSamplesPerSec == m_wfexDefault.nSamplesPerSec) (pwfex- nAvgBytesPerSec == m_wfexDefault.nAvgBytesPerSec)) { m_audioFormatCtrl.SetCurSel(n); pISC- SetFormat(pmt); } } } } else { m_audioFormatCtrl.AddString("ERROR Unable to retrieve audio formats"); } } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // PopulateCompressionControl // Fill compression control with a selection of video compressors, locate the // encoders and add them to the combo box if they exist. HRESULT CDecklinkCaptureDlg PopulateCompressionControl() { int n = m_compressionCtrl.AddString("Uncompressed"); m_compressionCtrl.SetItemData(n, (DWORD_PTR)ENC_NONE); // search for the DV encoder, MPEG encoder and WM encoder IBaseFilter* pFilter = NULL; HRESULT hr = CoCreateInstance(CLSID_DVVideoEnc, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast void** ( pFilter)); if (SUCCEEDED(hr)) { n = m_compressionCtrl.SetCurSel(m_compressionCtrl.AddString("DV Video Encoder")); m_compressionCtrl.SetItemData(n, (DWORD_PTR)ENC_DV); SAFE_RELEASE(pFilter); } hr = CoCreateInstance(CLSID_WMAsfWriter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast void** ( pFilter)); if (SUCCEEDED(hr)) { n = m_compressionCtrl.SetCurSel(m_compressionCtrl.AddString("Windows Media Encoder")); m_compressionCtrl.SetItemData(n, (DWORD_PTR)ENC_WM); SAFE_RELEASE(pFilter); } m_compressionCtrl.SetCurSel(m_compressor); return S_OK; } //----------------------------------------------------------------------------- // OnCbnSelchangeComboVideodevice // Rebuild graph with selected capture device void CDecklinkCaptureDlg OnCbnSelchangeComboVideodevice() { SAFE_RELEASE(m_pVideoCapture);// release our outstanding reference // remove intermediate filters, since the device selection has changed the capture device will also be removed HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // rebuild graph with new capture device selection PWSTR pName = (PWSTR)m_videoDeviceCtrl.GetItemData(m_videoDeviceCtrl.GetCurSel()); if (pName) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_VideoInputDeviceCategory, pName, m_pVideoCapture); if (SUCCEEDED(hr)) { // as the device has changed get the current operating format so that the control // and display this as the current selection CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pVideoCapture, MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // get the current format of the device to set the current selection of the control AM_MEDIA_TYPE* pamt = NULL; hr = pISC- GetFormat( pamt); if (SUCCEEDED(hr)) { if (pamt- pbFormat) { m_vihDefault = *(VIDEOINFOHEADER*)pamt- pbFormat; } DeleteMediaType(pamt); } } hr = PopulateVideoControl();// repopulate the control with formats from the new device if (SUCCEEDED(hr)) { hr = CreatePreviewGraph();// rebuild the graph with the new device } } } else { hr = E_POINTER; } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboAudiodevice // Rebuild graph with selected capture device void CDecklinkCaptureDlg OnCbnSelchangeComboAudiodevice() { SAFE_RELEASE(m_pAudioCapture);// release our outstanding reference // remove intermediate filters, since the device selection has changed the capture device will also be removed HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { PWSTR pName = (PWSTR)m_audioDeviceCtrl.GetItemData(m_audioDeviceCtrl.GetCurSel()); if (pName) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_AudioInputDeviceCategory, pName, m_pAudioCapture); if (SUCCEEDED(hr)) { // as the device has changed get the current operating format so that the control // and display this as the current selection CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pAudioCapture, MEDIATYPE_Audio, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // get the current format of the device to set the current selection of the control AM_MEDIA_TYPE* pamt = NULL; hr = pISC- GetFormat( pamt); if (SUCCEEDED(hr)) { if (pamt- pbFormat) { m_wfexDefault = *(WAVEFORMATEX*)pamt- pbFormat; } DeleteMediaType(pamt); } } hr = PopulateAudioControl();// repopulate the control with formats from the new device if (SUCCEEDED(hr)) { hr = CreatePreviewGraph();// rebuild the graph with the new device } } } else { hr = E_POINTER; } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboVideoformats // Rebuild preview graph if format selection changed void CDecklinkCaptureDlg OnCbnSelchangeComboVideoformats() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // locate the video capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pVideoCapture, MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // set the new media format AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(m_videoFormatCtrl.GetCurSel()); m_vihDefault = *(VIDEOINFOHEADER*)pmt- pbFormat; ASSERT(sizeof(VIDEOINFOHEADER) = pmt- cbFormat); hr = pISC- SetFormat(pmt); if (SUCCEEDED(hr)) { // save the new format EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoFormat", reinterpret_cast const BYTE* ( m_vihDefault), sizeof(m_vihDefault))); // update compression control, we don t have an HD compression filter so disable compression for HD formats if (576 m_vihDefault.bmiHeader.biHeight) { m_compressor = 0; m_compressionCtrl.SetCurSel(m_compressor); // save the new state EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoCompressor", reinterpret_cast const BYTE* ( m_compressor), sizeof(m_compressor))); m_bEnableCompressionCtrl = FALSE; } else { m_bEnableCompressionCtrl = TRUE; } EnableControls(); // rebuild the graph hr = CreatePreviewGraph(); } } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboAudioformats // Rebuild preview graph if format selection changed void CDecklinkCaptureDlg OnCbnSelchangeComboAudioformats() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // locate the audio capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pAudioCapture, MEDIATYPE_Audio, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // set the new media format AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)m_audioFormatCtrl.GetItemData(m_audioFormatCtrl.GetCurSel()); m_wfexDefault = *(WAVEFORMATEX*)pmt- pbFormat; ASSERT(sizeof(WAVEFORMATEX) == pmt- cbFormat); hr = pISC- SetFormat(pmt); if (SUCCEEDED(hr)) { // save the new format EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioFormat", reinterpret_cast const BYTE* ( m_wfexDefault), sizeof(m_wfexDefault))); // rebuild the graph hr = CreatePreviewGraph(); } } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboCompression // Rebuild preview graph if compression selection changed void CDecklinkCaptureDlg OnCbnSelchangeComboCompression() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // save the new state m_compressor = m_compressionCtrl.GetCurSel(); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoCompressor", reinterpret_cast const BYTE* ( m_compressor), sizeof(m_compressor))); // rebuild the graph hr = CreatePreviewGraph(); } } //----------------------------------------------------------------------------- // OnBnClickedCheckAudiomute // Rebuild the capture graph to reflect the new audio setting void CDecklinkCaptureDlg OnBnClickedCheckAudiomute() { CButton* pCheck = (CButton*)GetDlgItem(IDC_CHECK_AUDIOMUTE); if (pCheck) { m_bAudioMute = pCheck- GetState() 0x0003; HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // save the new state EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioMute", reinterpret_cast const BYTE* ( m_bAudioMute), sizeof(m_bAudioMute))); // rebuild the graph which reflects the new audio setting hr = CreatePreviewGraph(); } } } //----------------------------------------------------------------------------- // OnBnClickedButtonBrowse // Create a file open dialog to browse for a file location void CDecklinkCaptureDlg OnBnClickedButtonBrowse() { char BASED_CODE szFilters[] = "Windows Media Files|*.avi;*.asf;*.wmv|All Files (*.*)|*.*||"; char* pExt[] = {"*.avi", "*.avi", "*.asf;*.wmv"}; CFileDialog FileDlg(TRUE, "Windows Media Files", pExt[m_compressor], 0, szFilters, this); if (FileDlg.DoModal() == IDOK) { m_captureFile = FileDlg.GetPathName(); m_captureFileCtrl.SetWindowText(m_captureFile); } } //----------------------------------------------------------------------------- // OnBnClickedButtonCapture // Create a capture graph a start capture void CDecklinkCaptureDlg OnBnClickedButtonCapture() { HRESULT hr = CreateCaptureGraph(); if (SUCCEEDED(hr)) { if (m_pControl) { hr = m_pControl- Run(); if (SUCCEEDED(hr)) { DisableControls(); } } } } //----------------------------------------------------------------------------- // OnBnClickedButtonStop // Stop capture and revert to preview void CDecklinkCaptureDlg OnBnClickedButtonStop() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { hr = CreatePreviewGraph(); if (SUCCEEDED(hr)) { EnableControls(); } } } //----------------------------------------------------------------------------- // EnableControls // void CDecklinkCaptureDlg EnableControls(void) { CWnd* pWnd = GetDlgItem(IDC_COMBO_VIDEOFORMATS); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_COMBO_AUDIOFORMATS); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_CHECK_AUDIOMUTE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_COMBO_COMPRESSION); m_bEnableCompressionCtrl = (576 m_vihDefault.bmiHeader.biHeight) ? FALSE TRUE;// don t have an HDV codec do disable compression control for HD formats pWnd- EnableWindow(m_bEnableCompressionCtrl); pWnd = GetDlgItem(IDC_EDIT_CAPTUREFILE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_BUTTON_BROWSE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_BUTTON_CAPTURE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_BUTTON_STOP); pWnd- EnableWindow(FALSE); } //----------------------------------------------------------------------------- // DisableControls // void CDecklinkCaptureDlg DisableControls(void) { CWnd* pWnd = GetDlgItem(IDC_COMBO_VIDEOFORMATS); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_COMBO_AUDIOFORMATS); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_CHECK_AUDIOMUTE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_COMBO_COMPRESSION); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_EDIT_CAPTUREFILE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_BUTTON_BROWSE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_BUTTON_CAPTURE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_BUTTON_STOP); pWnd- EnableWindow(TRUE); } //----------------------------------------------------------------------------- // QueryRegistry // retrieve previous media formats from registry void CDecklinkCaptureDlg QueryRegistry(void) { if (ERROR_SUCCESS == m_regUtils.Open("DecklinkCaptureSample")) { EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("VideoFormat", reinterpret_cast LPBYTE ( m_vihDefault), sizeof(m_vihDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("AudioFormat", reinterpret_cast LPBYTE ( m_wfexDefault), sizeof(m_wfexDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("AudioMute", reinterpret_cast LPBYTE ( m_bAudioMute), sizeof(m_bAudioMute))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("VideoCompressor", reinterpret_cast LPBYTE ( m_compressor), sizeof(m_compressor))); WCHAR captureFile[MAX_PATH]; ZeroMemory(captureFile, sizeof(captureFile)); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetString("CaptureFile", reinterpret_cast LPBYTE (captureFile), sizeof(captureFile))); m_captureFile = captureFile; } else { // create the key and registry values if (ERROR_SUCCESS == m_regUtils.Create("DecklinkCaptureSample")) { EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoFormat", reinterpret_cast const BYTE* ( m_vihDefault), sizeof(m_vihDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioFormat", reinterpret_cast const BYTE* ( m_wfexDefault), sizeof(m_wfexDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioMute", reinterpret_cast const BYTE* ( m_bAudioMute), sizeof(m_bAudioMute))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoCompressor", reinterpret_cast const BYTE* ( m_compressor), sizeof(m_compressor))); } } // update mute audio check box control CButton* pButton = (CButton*)GetDlgItem(IDC_CHECK_AUDIOMUTE); pButton- SetCheck(m_bAudioMute); }
https://w.atwiki.jp/know-unix/pages/48.html
PowerBook G3 Pismo (G4 550MHz) で再生できる設定 Pismo ではh264とmkvでは無理。mpeg4とaviでエンコする事。 ffmpeg -i "input file" -b 3000k -s hd480 -ab 192k "output file" "-formats" でエンコード・デコード出来る種類確認出来る XBMC4XBOXでは720が再生出来るとされているがこれまたmpeg4とavi限定。 h264でファイルサイズを小さくしたい場合はhd480でエンコすればmkvでもxboxで再生可能。 その場合使う設定は以下: ffmpeg -i "your input file" -vcodec libx264 -s hd480 -acodec libfaac "your output file" ※なおh264を指定する場合今までのh264からlibx264へ代わった事に注目すべき。 http //wiki.xbmc.org/index.php?title=HOW-TO Use_Handbrake_on_Mac_to_encode_H.264_videos http //www.xbmc4xbox.org.uk/forum/viewtopic.php?t=1571 p=13475 Xbox のみを対象にする場合 Handbrake でエンコードしたほうが楽。 ーーーーーーーーーーーーーーーーーーーーー Xbox 動画考察 ーーーーーーーーーーーーーーーーーーーーー Xbox は非力なため動画の品質と容量のバランスに加えて、再生負荷も考慮する必要がある。 Handbrake でエンコする際負荷の少ないMPEG-4(FFMPEG)を選択するが(H.264に比べて)、その際 Constant Quality を選択するか Avg Bitrate を選択するかが課題となる。Avg を選択した場合容量は一定するが品質が一定しない。反面 CQ を選択すると容量にバラツキが生じ再生負荷も不均一となるが品質は一定する傾向にある。 試しに CQ の設定を 3 及び 1 で試してみるが負荷が高いせいか Xbox がフリーズする場面があった。6 に設定したところ現在までに問題は見受けられない。ファイル容量も25分程度の動画で180MBと比較的低い。しかしAvgで3000に設定した場合と比べると品質にやや難がある。とは言え480iのブラウン管では見分けがつかない(液晶PCモニタでは多少見劣りする)。 結局のところAvg 3000の方がごく僅かに画質が良く、海外ユーザーの間でも使用者が多いようなのでそちらにするか。 よって以下の設定を適用: Video settings | MPEG- 4 (Ffmpeg) / Average bitrate 3000kbps / Framerate (same as source) / (optional 2 pass encoding) Audio settings | Codec - auto passthru Subtitles | as you wish Chapters | as you wish Advanced | -maxrate 5000k -bufsize 4096k 結論: ISO状態のファイルは超高画質な上何ら問題なくXboxで再生できるのでそのままの状態を維持。他高解像度のMKVファイル等、Xboxでの再生に問題のあるファイルはHandbrakeにてエンコードする。その際の設定は上記に準じる。 ーーーーーーーーーーーーーーーーーーーーー This should still work on Handbrake for Windows or Linux but you may have to input the setting manually and save it. Some users have been unable to load the supplied preset on Windows. Tools VLC - Site or direct download for 64 Bit Mac Build 1.0.2 here Handbrake - Site Extras Handbrake Presets High Quality Low Quality (This is just a lower constant quality with MP3 audio) Or manually input this string and settings into the Advanced Settings box ref=2 me=hex bframes=3 8x8dct=0 subq=9 vbv-maxrate=2200 vbv-bufsize=2200 weightb=0 analyse=none no-dct-decimate=1 cabac=0 b-pyramid=none weightp=0 HB-advancedlarge.png Info For this encoding process I have prioritised video quality over file size. This is for encoding DVD sources to be used on the original xbox running xbmc. It uses the x264 codec so bitrate and advanced options have to be set specifically to allow it to run on old hardware. This is for use with AC3 or DTS passthrough. You can try it with MP3 or AAC audio, but no guarantees as this will require CPU for decoding. 1. Download VLC and Handbrake. Install them. On the Mac I would recommend running the 64 bit VLC build. 2. Download the Handbrake Presets and import them into Handbrake. 3. Load your source into Handbrake. You can rip straight from DVD using Handbrake, or load DVD images you have ripped previously with your ripper of choice. 4. Make sure you have either xbox-x264 or xbox-x264-LQ preset selected. 5. Make sure container is MKV. Audio is AC3 or DTS Passthrough. 6. You have to change some of the advanced settings if you used the presets in the attachments in the latest versions of Handbrake, since some of the defaults have been changed recently. Add " b-pyramid=none weightp=0" to the String you see in the bottom or uncheck "Weighted P-frames" and set "Pyramidal B-Frames" to off. end of line
https://w.atwiki.jp/maisenakajima/pages/28.html
errrno 一覧(RedHat Enterprise Linux 6.0) EPERM 1 Operation not permitted 許可されていない操作です ENOENT 2 No such file or directory そのようなファイルやディレクトリはありません ESRCH 3 No such process そのようなプロセスはありません EINTR 4 Interrupted system call システムコール割り込み EIO 5 I/O error 入力/出力エラーです ENXIO 6 No such device or address そのようなデバイスやアドレスはありません E2BIG 7 Argument list too long 引数リストが長すぎます ENOEXEC 8 Exec format error 実行形式エラー EBADF 9 Bad file number 不正なファイル記述子です ECHILD 10 No child processes 子プロセスがありません EAGAIN 11 Try again リソースが一時的に利用できません ENOMEM 12 Out of memory メモリを確保できません EACCES 13 Permission denied 許可がありません EFAULT 14 Bad address 不正なアドレスです ENOTBLK 15 Block device required ブロックデバイスが必要です EBUSY 16 Device or resource busy デバイスもしくはリソースがビジー状態です EEXIST 17 File exists ファイルが存在します EXDEV 18 Cross-device link 無効なクロスデバイスリンクです ENODEV 19 No such device そのようなデバイスはありません ENOTDIR 20 Not a directory ディレクトリではありません EISDIR 21 Is a directory ディレクトリです EINVAL 22 Invalid argument 無効な引数です ENFILE 23 File table overflow システム中のファイルを開きすぎです EMFILE 24 Too many open files ファイルを開きすぎです ENOTTY 25 Not a typewriter デバイスに対する不適切なioctlです ETXTBSY 26 Text file busy テキストファイルがビジー状態です EFBIG 27 File too large ファイルが大きすぎます ENOSPC 28 No space left on device デバイスに空き領域がありません ESPIPE 29 Illegal seek 不正なシークです EROFS 30 Read-only file system 読み込み専用ファイルシステムです EMLINK 31 Too many links リンクが多すぎます EPIPE 32 Broken pipe パイプが切断されました EDOM 33 Math argument out of domain of func 数値の引数はドメイン外です ERANGE 34 Math result not representable 計算結果は範囲外の値です EDEADLK 35 Resource deadlock would occur リソースのデッドロック回避 ENAMETOOLONG 36 File name too long ファイル名が長すぎます ENOLCK 37 No record locks available ロックが利用できません ENOSYS 38 Function not implemented 関数は実装されていません ENOTEMPTY 39 Directory not empty ディレクトリは空ではありません ELOOP 40 Too many symbolic links encountered シンボリックリンクの階層が多すぎます EWOULDBLOCK 41 Operation would block 未知のエラー EAGAIN 41 Operation would block 未知のエラー ENOMSG 42 No message of desired type 要求した形式のメッセージはありません EIDRM 43 Identifier removed 識別子を除去しました ECHRNG 44 Channel number out of range チャンネル番号が範囲外です EL2NSYNC 45 Level 2 not synchronized レベル2は同期していません EL3HLT 46 Level 3 halted レベル3停止 EL3RST 47 Level 3 reset レベル3はリセットしました ELNRNG 48 Link number out of range リンク数が範囲外です EUNATCH 49 Protocol driver not attached プロトコルドライバがアタッチされていません ENOCSI 50 No CSI structure available CSI 構造が利用できません EL2HLT 51 Level 2 halted レベル2停止 EBADE 52 Invalid exchange 無効な交換です EBADR 53 Invalid request descriptor 無効なリクエスト記述子です EXFULL 54 Exchange full Exchange full ENOANO 55 No anode アノードがありません EBADRQC 56 Invalid request code 無効なリクエストコードです EBADSLT 57 Invalid slot 無効なスロットです EDEADLOCK 58 未知のエラー EDEADLK 58 未知のエラー EBFONT 59 Bad font file format 不正なフォントファイル形式です ENOSTR 60 Device not a stream デバイスはストリーム型ではありません ENODATA 61 No data available 利用可能なデータがありません ETIME 62 Timer expired タイマが破棄されました ENOSR 63 Out of streams resources ストリームリソース外です ENONET 64 Machine is not on the network マシンはネットワークにつながっていません ENOPKG 65 Package not installed パッケージはインストールされていません EREMOTE 66 Object is remote オブジェクトはリモートにあります ENOLINK 67 Link has been severed リンクが切れています EADV 68 Advertise error Advertiseエラー ESRMNT 69 Srmount error Srmount エラー ECOMM 70 Communication error on send 送信中の通信エラー EPROTO 71 Protocol error プロトコルエラー EMULTIHOP 72 Multihop attempted 多重ホップが企てられました EDOTDOT 73 RFS specific error RFS特定エラー EBADMSG 74 Not a data message 不正なメッセージです EOVERFLOW 75 Value too large for defined data type 定義されたデータ型に対して値が大きすぎます ENOTUNIQ 76 Name not unique on network 名前がネットワーク上で重複しています EBADFD 77 File descriptor in bad state ファイル記述子が不正の状態にあります EREMCHG 78 Remote address changed 遠隔アドレスが変更されました ELIBACC 79 Can not access a needed shared library 必要な共有ライブラリにアクセスできません ELIBBAD 80 Accessing a corrupted shared library 壊れた共有ライブラリにアクセスしています ELIBSCN 81 .lib section in a.out corrupted a.out 中の .lib セクションが壊れています ELIBMAX 82 Attempting to link in too many shared libraries あまりに多過ぎる共有ライブラリへリンクしようとしています ELIBEXEC 83 Cannot exec a shared library directly 共有ライブラリは直接実行できません EILSEQ 84 Illegal byte sequence 無効または不完全なマルチバイトまたはワイド文字です ERESTART 85 Interrupted system call should be restarted 割り込まれたシステムコールは再スタートさせるべきです ESTRPIPE 86 Streams pipe error ストリームパイプエラー EUSERS 87 Too many users ユーザが多すぎます ENOTSOCK 88 Socket operation on non-socket ソケットでないものにソケット操作をしています EDESTADDRREQ 89 Destination address required 送信先アドレスが必要です EMSGSIZE 90 Message too long メッセージが長すぎます EPROTOTYPE 91 Protocol wrong type for socket ソケットに対し間違ったプロトコルの形式です ENOPROTOOPT 92 Protocol not available プロトコルは利用できません EPROTONOSUPPORT 93 Protocol not supported プロトコルはサポートされていません ESOCKTNOSUPPORT 94 Socket type not supported ソケット形式はサポートしていません EOPNOTSUPP 95 Operation not supported on transport endpoint サポートされていない操作です EPFNOSUPPORT 96 Protocol family not supported プロトコルファミリはサポートしていません EAFNOSUPPORT 97 Address family not supported by protocol アドレスファミリはプロトコルによってサポートされていません EADDRINUSE 98 Address already in use アドレスは既に使用中です EADDRNOTAVAIL 99 Cannot assign requested address 要求アドレスに割り当てられません ENETDOWN 100 Network is down ネットワークが落ちています ENETUNREACH 101 Network is unreachable ネットワークに届きません ENETRESET 102 Network dropped connection because of reset リセット中ネットワークの接続が切れました ECONNABORTED 103 Software caused connection abort ソフトウェアが接続を中断しました ECONNRESET 104 Connection reset by peer 接続が相手からリセットされました ENOBUFS 105 No buffer space available 利用可能な空きバッファがありません EISCONN 106 Transport endpoint is already connected 通信端点が既に接続されています ENOTCONN 107 Transport endpoint is not connected 通信端点が接続されていません ESHUTDOWN 108 Cannot send after transport endpoint shutdown 通信端点のシャットダウン後は送信できません ETOOMANYREFS 109 Too many references cannot splice 参照が多すぎます 接続できません ETIMEDOUT 110 Connection timed out 接続がタイムアウトしました ECONNREFUSED 111 Connection refused 接続を拒否されました EHOSTDOWN 112 Host is down ホストが落ちています EHOSTUNREACH 113 No route to host ホストへの経路がありません EALREADY 114 Operation already in progress 操作はすでに処理中です EINPROGRESS 115 Operation now in progress 現在処理中の操作です ESTALE 116 Stale NFS file handle 実効性のないNFSファイルハンドルです EUCLEAN 117 Structure needs cleaning 構造体を内容消去する必要があります ENOTNAM 118 Not a XENIX named type file XENIX の名前付きファイルではありません ENAVAIL 119 No XENIX semaphores available XENIX セマフォが利用できません EISNAM 120 Is a named type file 名前付きファイルです EREMOTEIO 121 Remote I/O error 遠隔I/Oエラーです EDQUOT 122 Quota exceeded ディスク使用量制限を超過しました ENOMEDIUM 123 No medium found メディアが見つかりません EMEDIUMTYPE 124 Wrong medium type 不正なメディア形式です ECANCELED 125 Operation Canceled 操作は中断されました ENOKEY 126 Required key not available EKEYEXPIRED 127 Key has expired EKEYREVOKED 128 Key has been revoked EKEYREJECTED 129 Key was rejected by service EOWNERDEAD 130 Owner died ENOTRECOVERABLE 131 State not recoverable ERFKILL 132 Operation not possible due to RF-kill 参考資料(RedHat Enterprise Linux 6.0) /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h Perl Script How to use system defined Error message
https://w.atwiki.jp/saibakho/pages/172.html
Google search 2.0(Google Mobile App Now Available) Google mobileサービス、様々な機能へのショートカットがある。 http //m.google.com/search/download/binaries/L1/2.1.11/GoogleSearch.sisx http //m.google.com/search/download/binaries/L1/2.1.12/GoogleSearch.sisx http //m.google.com/search/download/binaries/L1/2.3.8/GoogleSearch.sisx http //m.google.com/search/download/binaries/L1/2.3.9/GoogleSearch.sisx http //m.google.com/search/download/binaries/L1/2.3.10/GoogleSearch.sisx Google search 待受画面からGoogleで検索。そして、ノキアのブラウザが開く http //mobile.google.com/ http //www.google.com/m/download/msc http //www.google.com/m/download/iss/symbian_apps/1.0.15/L1/GoogleSearch.sisx http //www.google.com/m/download/iss/symbian_apps/1.0.19/L1/GoogleSearch.sisx http //www.google.com/m/download/iss/symbian_apps/1.1.0/L1/GoogleSearch.sisx http //www.google.com/m/download/iss/symbian_apps/1.1.4/L1/GoogleSearch.sisx Here and now 現在地のイベント情報と天気予報、 アプリでイベントのindexと大雑把な天気予報を表示 クリックするとブラウザが連動して詳細情報を表示 http //betalabs.nokia.com/betas/view/here-and-now Symarctic ExtGPS これにより、N95、E90、6110のGPSを、BlueTooth通信で他の機器が使えるようになる http //www.symarctic.com/beta/static.php?page=extgps_download http //www.joiku.com/index.php?action=products mode=productDetails product_id=351 http //www.symarctic.com/beta/images/extgps.jar Nokia Energy Profiler バッテリーの使用具合をグラフで確認できる x02nk用、705nkは不可 http //www.forum.nokia.com/info/sw.nokia.com/id/324866e9-0460-4fa4-ac53-01f0c392d40f/Nokia_Energy_Profiler.html http //sw.nokia.com/id/516b7ddb-bd31-483d-a7a5-25cb3f6b5f6e/Nokia_Energy_Profiler_1_1.sisx NAVITIME JAPAN 地図 E61やx02nkには対応。 705nkは非対応。 http //corporate.navitime.co.jp/smartphone/index.html Nokia Maps 2.0 firmware が(20.0.015 or newer)のx02nk/N95で使えるとの事 衛星写真が使えるようになる。日本の地図は大雑把。 http //maps.nokia.com/ Old version 3204 http //nds1.nokia.com/files/support/global/phones/software/Nokia_Maps_2.0_3204_3.1_u.sis 4503 http //nds1.nokia.com/files/support/global/phones/software/Nokia_Maps_2.0_4503_3.1_u.sis Nokia Map Loader 2.0.2 http //nds1.nokia.com/files/support/global/phones/software/NokiaMaploaderSetupJA.exe Nokia Maps 3.0 Beta(ovi) S60 3rd Edition Feature Pack 1と2で動作するらしいのでx02nkで動く 日本の地図は粗い たぶん、v2.0とv3.0の地図データは互換しなかった気がする http //betalabs.nokia.com/betas/view/nokia-maps-30-ovi-maps 地図をPCのブラウザから確認できる http //maps.ovi.com/services/integrated?lid=MapsBridge lang=ja-JP# Auto WeFi 無線LANの接続支援アプリ 接続先が複数ある場合に便利 http //www.wefi.com/ http //www.wefi.com/download/client/WeFi.sis Fon Symbianコネクションマネージャー https //www.fon.com/jp/support/fonMaterials http //www.fon.com/jp/download/popupOther?item=symbian HandyWi 無線LANのアクセスポイントがあると音で知らせてくれるらしい http //www.handywi.com/home.html Easy WiFi Devicescape 無線LAN自動接続 http //www.devicescape.com/pub/download.do X02nk用---モーションセンサ N95 RD Accelerometer Plug-inと対応アプリをインストールすることにより、 x02nk(N95)の隠された能力が使えるようになるらしい N95 RD Accelerometer Plug-in http //research.nokia.com/files/N95_RD_Accelerometer.zip FlipSilent 着信音やアラーム音(スヌーズ可)をひっくり返すことにより、止めることができるようになるアプリ V1.06はSymbian Signedらしい http //www.flipsilent.com/tongren/?q=node/29 http //thinkchange.cn/index.html http //www.flipsilent.com/tongren/?q=disknode/get/26/FlipSilentV1.06ExpSigned.sis download ShakeSMS モーションセンサにより、着信したSMSやMMSメールを振って開けるアプリ キーロック状態からでも開ける http //www.flipsilent.com/tongren/?q=node/31 http //www.flipsilent.com/tongren/?q=disknode/get/24/ShakeSMS-V1.02-SymbianSigned.sisx Nokia Step Counter(Nokia Activity Monitor) 万歩計 http //www.nokia.com/betalabs/stepcounter http //nds1.nokia.com//NOKIA_COM_1/Microsites/BetaLabs/applications/apps/NokiaStepCounter_beta_v021.sisx http //research.nokia.com/projects/activity_monitor http //research.nokia.com/files/ActivityMonitor_armv5_v011_N95.sisx http //nds1.nokia.com/NOKIA_COM_1/Microsites/BetaLabs/applications/apps/NokiaStepCounter_S60_3_1_beta.sis Nokia Headlines(Channels Media Service) NEWSが読めるアプリ。モーションセンサにより、画面が切り替わる機能付き http //www.nokia.com/betalabs/headlines http //nds1.nokia.com/NOKIA_COM_1/Microsites/BetaLabs/applications/apps/Headlines_02.0818.2_Batch3.SISX x02nk用---無線LANを使わないと沢山のパケット代が請求されそうなアプリ Voice over Internet Protocol Skype、fring、Gizmo(iSkoot,barablu,Nimbuzz,EQO,Truphone)などなど 数多くの企業がIP電話サービスを提供しているらしい Skype http //www.skype.com/intl/ja/download/skype/mobile/ http //www.skype.com/go/getskype-symbian-s60fp1 fring http //www.fring.com/download/ Gizmo http //www.nokia.com/A4403822 http //gizmo5.com/pc/ Nimbuzz http //www.nimbuzz.com/ 数多くあるVoIPの比較表 http //www.techcrunch.com/wp-content/voipcomparison.html http //www.s60tips.com/2007/06/28/which-voip-applications-to-use-part-v/ hotmixradio ネットラジオを聴くアプリ 日本のチャンネルがある アプリは下記URLをMobileのブラウザで開くとダウンロードリンクがある http //www.hotmixradio.fr/ InternetRadio 無線LANがあれば素晴らしいアプリとなる。 そうでなければパケ死する。 http //europe.nokia.com/A41121127 http //nds1.nokia.com/EUROPE_NOKIA_COM_3/Explore_services/Nokia_Music/Support/downloadable_files/InternetRadio_31_n95.SIS http //nds1.nokia.com/EUROPE_NOKIA_COM_3/Explore_services/Nokia_Music/Support/downloadable_files/v18_InternetRadioUpdate31.SIS Picasa photo browser Picasaを見る為のアプリかな、たぶん http //www.getjar.com/products/14834/Picasa http //www.symbian-freak.com/news/008/03/picasa_photo_browser.htm Google Picasa Web Albums for S60 携帯電話のWeb browserからも見れるとの事らしい http //www.symbian-freak.com/news/008/06/picasa_photo_browser_for_s60.htm http //picasaweb.google.com/ YouTube for Nokia/Symbian S60 Devices sisxバージョンのYouTubeアプリ http //www.google.com/support/youtube/bin/answer.py?hl=en answer=142850 Old version http //m.google.com/youtube/download/binaries/L1/2.4.4/youtube.sisx YouTube for Mobile 携帯電話用のYouTube 携帯電話からアクセスすると、ダウンロードできるらしい 説明文 http //internet.watch.impress.co.jp/cda/news/2008/01/25/18229.html 705nkでもunsigned versionでインストールできるがパケ死する可能性大 Hiisi Proxy不可、肝心のムービー部分でProxyを無視する、パッチ不可 アプリと携帯電話用のサイトがある。 互いにRealPlayerでstreaming再生。 Mobile用サイト http //m.jp.youtube.com/ アプリダウンロード先 http //m.youtube.com/app Old version unsignedなjadファイル http //www.google.com/m/download/youtube/youtube.jad?ver=v1.4.5 sign=0 gl=JP client=mv-google hl=ja signedなjadファイル http //www.google.com/m/download/youtube/youtube.jad?sign=1 ver=v1.4.5 gl=JP client=mv-google hl=ja jarファイル http //www.google.com/m/download/youtube/apps/v1.4.5/L1/minitube-145-n60_L1.jar Open Video Hub YouTube Daily Motion Metacafe http //openvideohub.com/index.html#about Revnx Video Streaming and Broadcast RevnxというサイトのVideoや写真を見ることが出来るアプリ 動画は、streaming再生する(たぶんアプリ上で再生)。 http //www.revnx.com/ http //m.revnx.com/ http //www.getjar.com/products/16625/RevnxVideoStreamingandBroadcast http //m.revnx.com/install/v/Revnx.jad http //m.revnx.com/install/v/Revnx.jad ストリーミング動画配信サービス Ustream x02nkのカメラにて、ストリーミング動画配信サービスを利用するアプリ 設定したオプションが反映したりしなかったりと不安定かもしれない20091119 http //www.ustream.tv/mobile/broadcaster http //www.ustream.tv/s60 Flixwagon 動画の録画をベースとしてるのかな 録画をベースの分、他のサービスより少しだけ画質が綺麗なストリーミングの配信ができるかもしれない データの転送が遅れてしまうと、LIVE映像がカクカクしてしまうかもしれません オプションの設定が反映したりしなかったりするかも20091119 http //www.flixwagon.com/ mobile http //m.flixwagon.com/ Stickam Mobile ストリーミング動画配信サービスを利用するアプリ 人気サイト、視聴サイト自体が少し動作が重いかもしれない http //stickam.com/ 国内サイトはメールで動画をアップできるらしい http //www.stickam.jp/ mobile http //m.stickam.com/ http //m.stickam.com/s60/stickam.sisx Bambuser mobileでの撮影を基本にしているのかな 低機能、軽動作かもしれません20091119 http //bambuser.com/ mobile http //m.bambuser.com/ http //m.bambuser.com/dl.php?v=S60v3 b=Nokia m=N95 GPS Live Media GPS video+GPSトラッキング ビデオの撮影と同時にGPSトラッキング情報を記録してくれるアプリ 撮影したビデオを専用サイトにアプロードすると、地図で移動ルートを確認しながら録画映像を見ることができる。 http //www.ix-m.com/ オンラインシェアリング 各ブログ提供サイトに手軽に写真や動画などを投稿できるサービス オンラインシェアリングのリストに無いサイトはcfgファイルで追加できることもあるらしい pixelpipe Share online連携サービス、twitterなど、様々なサイトへ対応している。 http //pixelpipe.com/ http //m.pixelpipe.com/nokia 対応サイト一覧 http //pixelpipe.com/capabilities mixi mixi(ミクシィ)は、株式会社ミクシィが運営する、日本最大級のシェアを持つソーシャル・ネットワーキング・サービス (SNS)らしい http //mixi.jp/ セットアップ説明 Nokia N73 Phone Support The config file http //mixi.jp/atom/mixi_configuration_file.cfg flickr! Flickr(フリッカー、フリックガンマ)は、デジタルカメラなどによる写真を共有するコミュニティサイトらしい http //www.flickr.com/ セットアップ説明 Flickr Configure Your Nokia N73 http //flickr.com/nokia/configure/n73/ The config file http //flickr.com/services/atom/config/nokia/nseries/flickr_configuration_file.cfg?dl=1 http //europe.nokia.com/support/nokiaphotos Vox Vox(ぼっくす)は、ブログの会社であるシックス・アパートが2006年10月26日に開始したサービスらしい http //go.vox.com/nokia/ The config file http //www.vox.com/services/config/vox_configuration_file.cfg ovi 端末がv3.0以降であるのが望ましいらしい。 http //share.ovi.com/ http //cid-8fab59d2294729b6.skydrive.live.com/self.aspx/Nokia%20N95%20app/Share%20Online/ovishare.cfg Blog、twitterなど ShoZu 様々なBlogサイトやPhoto Sharingサイトや動画サイトにアップロードを支援するアプリ ShoZuで登録後に使用。 大抵の有名サイトには対応している。 ただし、サイトによっては送信データに日本語を含めるとアップロードを失敗することがあるらしい http //www.shozu.com/portal/index.do http //www.shozu.com/d/s60v3fp1/shozu.sisx orkut 内容は気軽に出来無いSNSらしい アカウントは気軽なGoogleアカウントを使えるらしい Wikipedia http //www.orkut.com/ http //m.google.com/orkut/download/orkut.jad?dc=gorganic hl=en-GB ver=1.0.0 http //m.google.com/orkut/download/binaries/L1/1.0.0/orkut_m2.jar http //m.google.com/orkut/download/orkut.jad?dc=gorganic hl=en ver=1.3.0 http //m.google.com/orkut/download/binaries/L1/1.3.0/orkut_m2.jar mobileサイト http //m.orkut.com/ Tweets60 twitter シンプルで軽快な動作 http //tweets60.com/index.php http //tweets60.com/download/tweets60_1_22.sisx http //tweets60.com/download/tweets60_1_26.sisx http //tweets60.com/download/tweets60_1_28.sisx http //tweets60.com/download/tweets60_1_32.sisx http //tweets60.com/download/tweets60_1_34_1.sisx http //tweets60.com/download/tweets60_1_36_1_lite.sisx http //tweets60.com/download/tweets60_1_36_2_lite.sisx http //tweets60.com/download/tweets60_1_36_3_lite.sisx http //tweets60.com/download/Tweets60_1_38_0_lite_Express_Signed.sisx http //tweets60.com/download/Tweets60_lite.sisx http //tweets60.com/download/latest.php Twibble つぶやき、twitter 高機能、少しゴチャゴチャしている http //www.twibble.de/twibble-mobile/ http //www.twibble.de/sw/mobile/all/twibble.jad http //www.twibble.de/sw/mobile/all/twibble.jar tvider Lite tvider Liteはtwitterへのマルチメディアファイルの投稿に特化したアプリ。 画像や動画や音声をアプリ上で撮影や録音して投稿する形式をとる。 また、tvider使用者全体のツブヤキ、tvider使用のFriendsを確認することが出来るらしい。 http //tvider.com/mobile http //file.umundo.com/build/tvider/Umundo/Default/symbian/Default/tvider.sis Snaptu 様々なリンク集などのアプリかな http //snaptu.com/ http //m.snaptu.com/
https://w.atwiki.jp/bmd_intensity/pages/18.html
//------------------------------------------------------------------------------------ // $Id Utils.cpp,v 1.10 2006/04/11 01 13 06 ivanr Exp $ // // Desc DirectShow utility class implementation // // Copyright (c) Blackmagic Design 2005. All rights reserved. //------------------------------------------------------------------------------------ #include "stdafx.h" #include "Utils.h" //----------------------------------------------------------------------------- // CDSUtils - Directshow utility class //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // AddFilter // Attempts to locate a filter of a given class ID and nameand add it to the graph HRESULT CDSUtils AddFilter(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter) { HRESULT hr = S_OK; if (pGraph pName ppFilter) { *ppFilter = NULL; IBaseFilter* pFilter = NULL; hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast void** ( pFilter)); if (SUCCEEDED(hr)) { hr = pGraph- AddFilter(pFilter, pName); if (SUCCEEDED(hr)) { *ppFilter = pFilter; } else { SAFE_RELEASE(pFilter); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // AddFilter2 // Attempts to locate a filter of a given class category and name HRESULT CDSUtils AddFilter2(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter) { HRESULT hr = S_OK; if (pGraph pName ppFilter) { // first enumerate the system devices for the specifed class and filter name CComPtr ICreateDevEnum pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast void** ( pSysDevEnum)); if (SUCCEEDED(hr)) { CComPtr IEnumMoniker pEnumCat = NULL; hr = pSysDevEnum- CreateClassEnumerator(clsid, pEnumCat, 0); if (S_OK == hr) { IMoniker* pMoniker = NULL; bool Loop = true; while ((S_OK == pEnumCat- Next(1, pMoniker, NULL)) Loop) { IPropertyBag* pPropBag = NULL; hr = pMoniker- BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast void** ( pPropBag)); if (SUCCEEDED(hr)) { VARIANT varName; VariantInit( varName); hr = pPropBag- Read(L"FriendlyName", varName, 0); if (SUCCEEDED(hr)) { if (0 == wcscmp(varName.bstrVal, pName)) { hr = pMoniker- BindToObject(NULL, NULL, IID_IBaseFilter, reinterpret_cast void** (ppFilter)); Loop = false; } } VariantClear( varName); // contained within a loop, decrement the reference count SAFE_RELEASE(pPropBag); } SAFE_RELEASE(pMoniker); } } } // if a filter has been located add it to the graph if (*ppFilter) { hr = pGraph- AddFilter(reinterpret_cast IBaseFilter* (*ppFilter), pName); } else { hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; } //------------------------------------------------------------------------------------------------- // GetUnconnectedPin // Attemptes to locate an unconnected pin on filter HRESULT CDSUtils GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter ppPin) { CComPtr IEnumPins pEnum = NULL; IPin* pPin = NULL; hr = pFilter- EnumPins( pEnum); if (SUCCEEDED(hr)) { while (pEnum- Next(1, pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin- QueryDirection( ThisPinDir); if (ThisPinDir == PinDir) { IPin* pPinTemp = NULL; hr = pPin- ConnectedTo( pPinTemp); if (SUCCEEDED(hr)) { SAFE_RELEASE(pPinTemp); } else { // unconnected, return this pin *ppPin = pPin; hr = S_OK; break; } } SAFE_RELEASE(pPin); } } if (NULL == *ppPin) { // failed to find an unconnected pin hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // GetPin // Find the pin of the specified name on the given filter // This method leaves an outstanding reference on the pin if successful HRESULT CDSUtils GetPin(IBaseFilter* pFilter, const wchar_t* pName, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter pName ppPin) { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { IPin* pIPin = NULL; while (S_OK == pIEnumPins- Next(1, pIPin, NULL)) { PIN_INFO info = {0}; hr = pIPin- QueryPinInfo( info); if (SUCCEEDED(hr)) { SAFE_RELEASE(info.pFilter); if (0 == wcsncmp(info.achName, pName, wcslen(pName))) { // matched the pin category *ppPin = pIPin; break; } } SAFE_RELEASE(pIPin); } } if (NULL == *ppPin) { // failed to find the named pin hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // GetPin // Find the pin of the specified format type on the given filter // This method leaves an outstanding reference on the pin if successful HRESULT CDSUtils GetPin(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter pFormat ppPin) { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { // find the pin with the specified format IPin* pIPin = NULL; while (S_OK == pIEnumPins- Next(1, pIPin, NULL)) { // match the pin direction PIN_DIRECTION pinDir; pIPin- QueryDirection( pinDir); if (pinDir == PinDir) { // match pin direction check the first media type returned from the upstream pin CComPtr IEnumMediaTypes pIEnumMT = NULL; hr = pIPin- EnumMediaTypes( pIEnumMT); if (SUCCEEDED(hr)) { AM_MEDIA_TYPE* pmt = NULL; hr = pIEnumMT- Next(1, pmt, NULL); if (S_OK == hr) { if (pmt- majortype == *pFormat) { // found the pin with the specified format *ppPin = pIPin; DeleteMediaType(pmt); break; } else { DeleteMediaType(pmt); } } } } SAFE_RELEASE(pIPin); } if (NULL == *ppPin) { // failed to find the named pin hr = E_FAIL; } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // ConnectFiltersNamedPin // Connects two filters using the pin names, if no name is supplied the first // unconnected pin is used HRESULT CDSUtils ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName, IBaseFilter* pDownstream, wchar_t* pDownstreamPinName) { HRESULT hr = S_OK; if (pUpstream pDownstream) { // get the upstream output pin CComPtr IPin pIPinOutput = NULL; if (pUpstreamPinName) { hr = GetPin(pUpstream, pUpstreamPinName, pIPinOutput); } else { hr = GetUnconnectedPin(pUpstream, PINDIR_OUTPUT, pIPinOutput); } if (SUCCEEDED(hr)) { // get the downstream input pin CComPtr IPin pIPinInput = NULL; if (pDownstreamPinName) { hr = GetPin(pDownstream, pDownstreamPinName, pIPinInput); } else { hr = GetUnconnectedPin(pDownstream, PINDIR_INPUT, pIPinInput); } if (SUCCEEDED(hr)) { // connect the pins hr = pGraph- Connect(pIPinOutput, pIPinInput); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // ConnectFilters // Connects two filters by finding a pin on the upstream filter with the specified // major format type, e.g. For connecting an audio pin to a downstream filter HRESULT CDSUtils ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, IBaseFilter* pDownstream, const GUID* pFormat) { HRESULT hr = S_OK; if (pUpstream pDownstream pFormat) { // find the upstream output pin with the specified format CComPtr IPin pIPinOutput = NULL; hr = GetPin(pUpstream, pFormat, PINDIR_OUTPUT, pIPinOutput); if (SUCCEEDED(hr)) { // get the downstream input pin CComPtr IPin pIPinInput = NULL; hr = GetPin(pDownstream, pFormat, PINDIR_INPUT, pIPinInput); if (SUCCEEDED(hr)) { // connect the pins hr = pGraph- Connect(pIPinOutput, pIPinInput); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // RenderFilter // Renders the named output pin of the filter, or the first unconnected output if // no name is provided HRESULT CDSUtils RenderFilter(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName) { HRESULT hr = S_OK; if (pUpstream) { CComPtr IPin pIPinOutput = NULL; if (pUpstreamPinName) { hr = GetPin(pUpstream, pUpstreamPinName, pIPinOutput); } else { hr = GetUnconnectedPin(pUpstream, PINDIR_OUTPUT, pIPinOutput); } if (SUCCEEDED(hr)) { hr = pGraph- Render(pIPinOutput); } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // DisconnectAllPins // Disconnect all the pins of the filters in a graph HRESULT CDSUtils DisconnectAllPins(IGraphBuilder* pGraph) { HRESULT hr = S_OK; if (pGraph) { CComPtr IEnumFilters pIEnumFilters = NULL; hr = pGraph- EnumFilters( pIEnumFilters); if (SUCCEEDED(hr)) { IBaseFilter* pFilter = NULL; while (S_OK == pIEnumFilters- Next(1, pFilter, NULL)) { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { IPin* pIPin = NULL; while (S_OK == pIEnumPins- Next(1, pIPin, NULL)) { IPin* pIPinConnection = NULL; if (S_OK == pIPin- ConnectedTo( pIPinConnection)) { // pins are connected, to disconnect filters, both pins must be disconnected hr = pGraph- Disconnect(pIPin); hr = pGraph- Disconnect(pIPinConnection); SAFE_RELEASE(pIPinConnection); } SAFE_RELEASE(pIPin); } } SAFE_RELEASE(pFilter); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // FindFilterInterface // Attempt to locate the specified interface HRESULT CDSUtils FindFilterInterface(IBaseFilter* pFilter, const IID riid, void** ppvInterface) { HRESULT hr = S_OK; if (pFilter ppvInterface) { hr = pFilter- QueryInterface(riid, ppvInterface); } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // FindPinInterface // Attempt to locate the interface on the named pin or on the first pin if no // name is provided. HRESULT CDSUtils FindPinInterface(IBaseFilter* pFilter, wchar_t* pName, const IID riid, void** ppvInterface) { HRESULT hr = S_OK; if (pFilter ppvInterface) { CComPtr IPin pIPin = NULL; if (pName) { hr = GetPin(pFilter, pName, pIPin); } else { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { hr = pIEnumPins- Next(1, pIPin, NULL); } } if (SUCCEEDED(hr)) { hr = pIPin- QueryInterface(riid, ppvInterface); } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // FindPinInterface // Attempt to locate the interface on the pin with the specified format or on the first pin if no // format is provided. HRESULT CDSUtils FindPinInterface(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, const IID riid, void** ppvInterface) { HRESULT hr = S_OK; if (pFilter ppvInterface) { CComPtr IPin pIPin = NULL; if (pFormat) { hr = GetPin(pFilter, pFormat, PinDir, pIPin); } else { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { hr = pIEnumPins- Next(1, pIPin, NULL); } } if (SUCCEEDED(hr)) { hr = pIPin- QueryInterface(riid, ppvInterface); } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // AddGraphToRot // Adds a DirectShow filter graph to the Running Object Table, // allowing GraphEdit to "spy" on a remote filter graph. HRESULT CDSUtils AddGraphToRot(IUnknown* pUnkGraph, DWORD* pdwRegister) { HRESULT hr = S_OK; if (pUnkGraph pdwRegister) { CComPtr IRunningObjectTable pROT = NULL; hr = GetRunningObjectTable(0, pROT); if (SUCCEEDED(hr)) { WCHAR wsz[128]; StringCchPrintfW(wsz, 128, L"FilterGraph %08x pid %08x\0", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); CComPtr IMoniker pMoniker = NULL; hr = CreateItemMoniker(L"!", wsz, pMoniker); if(SUCCEEDED(hr)) { // Use the ROTFLAGS_REGISTRATIONKEEPSALIVE to ensure a strong reference // to the object. Using this flag will cause the object to remain // registered until it is explicitly revoked with the Revoke() method. // // Not using this flag means that if GraphEdit remotely connects // to this graph and then GraphEdit exits, this object registration // will be deleted, causing future attempts by GraphEdit to fail until // this application is restarted or until the graph is registered again. hr = pROT- Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker, pdwRegister); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // RemoveGraphFromRot // Removes a filter graph from the Running Object Table void CDSUtils RemoveGraphFromRot(DWORD pdwRegister) { CComPtr IRunningObjectTable pROT = NULL; if (SUCCEEDED(GetRunningObjectTable(0, pROT))) { pROT- Revoke(pdwRegister); } } //------------------------------------------------------------------------------------ // CRegUtils - Registry utility class //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ // Constructor // CRegUtils CRegUtils() m_hKey(NULL) { } //------------------------------------------------------------------------------------ // Destructor // CRegUtils ~CRegUtils() { Close(); } //------------------------------------------------------------------------------------ // Open // Opens the specified subkey LONG CRegUtils Open(LPCTSTR lpSubKey) { Close(); m_subKeyName = "Software\\Blackmagic Design\\Samples\\"; m_subKeyName += lpSubKey; return RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_subKeyName.c_str(), 0, KEY_ALL_ACCESS, m_hKey); } //------------------------------------------------------------------------------------ // Create // Creates the specified subkey LONG CRegUtils Create(LPCTSTR lpSubKey) { Close(); m_subKeyName = "Software\\Blackmagic Design\\Samples\\"; m_subKeyName += lpSubKey; return RegCreateKeyEx(HKEY_LOCAL_MACHINE, m_subKeyName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, m_hKey, NULL); } //------------------------------------------------------------------------------------ // Close // Closes the subkey void CRegUtils Close() { RegCloseKey(m_hKey); m_hKey = NULL; m_subKeyName.empty(); } //------------------------------------------------------------------------------------ // SetString // Set the key for the named value of type string LONG CRegUtils SetString(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) { return RegSetValueEx(m_hKey, valueName, 0, REG_SZ, lpData, cbData); } //------------------------------------------------------------------------------------ // GetString // Query the key for the named value of type string LONG CRegUtils GetString(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) { LONG ret = ERROR_SUCCESS; DWORD size = cbData, type = 0; ret = RegQueryValueEx(m_hKey, valueName, NULL, type, lpData, size); if ((size != cbData) || (REG_SZ != type)) { ret = ERROR_INVALID_PARAMETER; } return ret; } //------------------------------------------------------------------------------------ // SetBinary // Set the key for the named value of type binary LONG CRegUtils SetBinary(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) { return RegSetValueEx(m_hKey, valueName, 0, REG_BINARY, lpData, cbData); } //------------------------------------------------------------------------------------ // GetBinary // Query the key for the named value of type binary LONG CRegUtils GetBinary(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) { LONG ret = ERROR_SUCCESS; DWORD size = cbData, type = 0; ret = RegQueryValueEx(m_hKey, valueName, NULL, type, lpData, size); if ((size != cbData) || (REG_BINARY != type)) { ret = ERROR_INVALID_PARAMETER; } return ret; } //------------------------------------------------------------------------------------ // SetDword // Set the key for the named value of type DWORD LONG CRegUtils SetDword(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) { return RegSetValueEx(m_hKey, valueName, 0, REG_DWORD, lpData, cbData); } //------------------------------------------------------------------------------------ // GetDword // Query the key for the named value of type DWORD LONG CRegUtils GetDword(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) { LONG ret = ERROR_SUCCESS; DWORD size = cbData, type = 0; ret = RegQueryValueEx(m_hKey, valueName, NULL, type, lpData, size); if ((size != cbData) || (REG_DWORD != type)) { ret = ERROR_INVALID_PARAMETER; } return ret; } //------------------------------------------------------------------------------------ // CUtils - utility class //------------------------------------------------------------------------------------ //----------------------------------------------------------------------------- // GetBMIHeader // Returns the BITMAPINFOHEADER structure from media type format extension BITMAPINFOHEADER* CUtils GetBMIHeader(const AM_MEDIA_TYPE* pamt) { BITMAPINFOHEADER* pbmih = NULL; if (pamt) { if (FORMAT_VideoInfo == pamt- formattype) { VIDEOINFOHEADER* pvih = reinterpret_cast VIDEOINFOHEADER* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER) = pamt- cbFormat); pbmih = pvih- bmiHeader; } else if (FORMAT_VideoInfo2 == pamt- formattype) { VIDEOINFOHEADER2* pvih = reinterpret_cast VIDEOINFOHEADER2* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER2) = pamt- cbFormat); pbmih = pvih- bmiHeader; } } return pbmih; } //----------------------------------------------------------------------------- // GetBMIHeader // Returns the BITMAPINFOHEADER structure from media type format extension BITMAPINFOHEADER* CUtils GetBMIHeader(const CMediaType mt) { BITMAPINFOHEADER* pbmih = NULL; if (FORMAT_VideoInfo == mt.formattype) { VIDEOINFOHEADER* pvih = reinterpret_cast VIDEOINFOHEADER* (mt.pbFormat); ASSERT(sizeof(VIDEOINFOHEADER) = mt.cbFormat); pbmih = pvih- bmiHeader; } else if (FORMAT_VideoInfo2 == mt.formattype) { VIDEOINFOHEADER2* pvih = reinterpret_cast VIDEOINFOHEADER2* (mt.pbFormat); ASSERT(sizeof(VIDEOINFOHEADER2) = mt.cbFormat); pbmih = pvih- bmiHeader; } return pbmih; } //----------------------------------------------------------------------------- // GetAvgTimePerFrame // Returns the average time per frame from media type format extension REFERENCE_TIME CUtils GetAvgTimePerFrame(const AM_MEDIA_TYPE* pamt) { REFERENCE_TIME rtAvgTimePerFrame = 0; if (pamt) { if (FORMAT_VideoInfo == pamt- formattype) { VIDEOINFOHEADER* pvih = reinterpret_cast VIDEOINFOHEADER* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER) = pamt- cbFormat); rtAvgTimePerFrame = pvih- AvgTimePerFrame; } else if (FORMAT_VideoInfo2 == pamt- formattype) { VIDEOINFOHEADER2* pvih = reinterpret_cast VIDEOINFOHEADER2* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER2) = pamt- cbFormat); rtAvgTimePerFrame = pvih- AvgTimePerFrame; } } return rtAvgTimePerFrame; } //------------------------------------------------------------------------------------ // GetImageSize // Calculates the image size unsigned long CUtils GetImageSize(BITMAPINFOHEADER* pbmih) { unsigned long dwImageSize = 0; if (pbmih) { switch (pbmih- biCompression) { default case BI_RGB dwImageSize = (pbmih- biWidth * abs(pbmih- biHeight) * pbmih- biBitCount) 3; break; case YVYU case 2YUY dwImageSize = (pbmih- biWidth * abs(pbmih- biHeight) * 16) 3; break; } } return dwImageSize; }
https://w.atwiki.jp/intensity/pages/22.html
//------------------------------------------------------------------------------------ // $Id Utils.cpp,v 1.10 2006/04/11 01 13 06 ivanr Exp $ // // Desc DirectShow utility class implementation // // Copyright (c) Blackmagic Design 2005. All rights reserved. //------------------------------------------------------------------------------------ #include "stdafx.h" #include "Utils.h" //----------------------------------------------------------------------------- // CDSUtils - Directshow utility class //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // AddFilter // Attempts to locate a filter of a given class ID and nameand add it to the graph HRESULT CDSUtils AddFilter(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter) { HRESULT hr = S_OK; if (pGraph pName ppFilter) { *ppFilter = NULL; IBaseFilter* pFilter = NULL; hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast void** ( pFilter)); if (SUCCEEDED(hr)) { hr = pGraph- AddFilter(pFilter, pName); if (SUCCEEDED(hr)) { *ppFilter = pFilter; } else { SAFE_RELEASE(pFilter); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // AddFilter2 // Attempts to locate a filter of a given class category and name HRESULT CDSUtils AddFilter2(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter) { HRESULT hr = S_OK; if (pGraph pName ppFilter) { // first enumerate the system devices for the specifed class and filter name CComPtr ICreateDevEnum pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast void** ( pSysDevEnum)); if (SUCCEEDED(hr)) { CComPtr IEnumMoniker pEnumCat = NULL; hr = pSysDevEnum- CreateClassEnumerator(clsid, pEnumCat, 0); if (S_OK == hr) { IMoniker* pMoniker = NULL; bool Loop = true; while ((S_OK == pEnumCat- Next(1, pMoniker, NULL)) Loop) { IPropertyBag* pPropBag = NULL; hr = pMoniker- BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast void** ( pPropBag)); if (SUCCEEDED(hr)) { VARIANT varName; VariantInit( varName); hr = pPropBag- Read(L"FriendlyName", varName, 0); if (SUCCEEDED(hr)) { if (0 == wcscmp(varName.bstrVal, pName)) { hr = pMoniker- BindToObject(NULL, NULL, IID_IBaseFilter, reinterpret_cast void** (ppFilter)); Loop = false; } } VariantClear( varName); // contained within a loop, decrement the reference count SAFE_RELEASE(pPropBag); } SAFE_RELEASE(pMoniker); } } } // if a filter has been located add it to the graph if (*ppFilter) { hr = pGraph- AddFilter(reinterpret_cast IBaseFilter* (*ppFilter), pName); } else { hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; } //------------------------------------------------------------------------------------------------- // GetUnconnectedPin // Attemptes to locate an unconnected pin on filter HRESULT CDSUtils GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter ppPin) { CComPtr IEnumPins pEnum = NULL; IPin* pPin = NULL; hr = pFilter- EnumPins( pEnum); if (SUCCEEDED(hr)) { while (pEnum- Next(1, pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin- QueryDirection( ThisPinDir); if (ThisPinDir == PinDir) { IPin* pPinTemp = NULL; hr = pPin- ConnectedTo( pPinTemp); if (SUCCEEDED(hr)) { SAFE_RELEASE(pPinTemp); } else { // unconnected, return this pin *ppPin = pPin; hr = S_OK; break; } } SAFE_RELEASE(pPin); } } if (NULL == *ppPin) { // failed to find an unconnected pin hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // GetPin // Find the pin of the specified name on the given filter // This method leaves an outstanding reference on the pin if successful HRESULT CDSUtils GetPin(IBaseFilter* pFilter, const wchar_t* pName, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter pName ppPin) { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { IPin* pIPin = NULL; while (S_OK == pIEnumPins- Next(1, pIPin, NULL)) { PIN_INFO info = {0}; hr = pIPin- QueryPinInfo( info); if (SUCCEEDED(hr)) { SAFE_RELEASE(info.pFilter); if (0 == wcsncmp(info.achName, pName, wcslen(pName))) { // matched the pin category *ppPin = pIPin; break; } } SAFE_RELEASE(pIPin); } } if (NULL == *ppPin) { // failed to find the named pin hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // GetPin // Find the pin of the specified format type on the given filter // This method leaves an outstanding reference on the pin if successful HRESULT CDSUtils GetPin(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter pFormat ppPin) { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { // find the pin with the specified format IPin* pIPin = NULL; while (S_OK == pIEnumPins- Next(1, pIPin, NULL)) { // match the pin direction PIN_DIRECTION pinDir; pIPin- QueryDirection( pinDir); if (pinDir == PinDir) { // match pin direction check the first media type returned from the upstream pin CComPtr IEnumMediaTypes pIEnumMT = NULL; hr = pIPin- EnumMediaTypes( pIEnumMT); if (SUCCEEDED(hr)) { AM_MEDIA_TYPE* pmt = NULL; hr = pIEnumMT- Next(1, pmt, NULL); if (S_OK == hr) { if (pmt- majortype == *pFormat) { // found the pin with the specified format *ppPin = pIPin; DeleteMediaType(pmt); break; } else { DeleteMediaType(pmt); } } } } SAFE_RELEASE(pIPin); } if (NULL == *ppPin) { // failed to find the named pin hr = E_FAIL; } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // ConnectFiltersNamedPin // Connects two filters using the pin names, if no name is supplied the first // unconnected pin is used HRESULT CDSUtils ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName, IBaseFilter* pDownstream, wchar_t* pDownstreamPinName) { HRESULT hr = S_OK; if (pUpstream pDownstream) { // get the upstream output pin CComPtr IPin pIPinOutput = NULL; if (pUpstreamPinName) { hr = GetPin(pUpstream, pUpstreamPinName, pIPinOutput); } else { hr = GetUnconnectedPin(pUpstream, PINDIR_OUTPUT, pIPinOutput); } if (SUCCEEDED(hr)) { // get the downstream input pin CComPtr IPin pIPinInput = NULL; if (pDownstreamPinName) { hr = GetPin(pDownstream, pDownstreamPinName, pIPinInput); } else { hr = GetUnconnectedPin(pDownstream, PINDIR_INPUT, pIPinInput); } if (SUCCEEDED(hr)) { // connect the pins hr = pGraph- Connect(pIPinOutput, pIPinInput); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // ConnectFilters // Connects two filters by finding a pin on the upstream filter with the specified // major format type, e.g. For connecting an audio pin to a downstream filter HRESULT CDSUtils ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, IBaseFilter* pDownstream, const GUID* pFormat) { HRESULT hr = S_OK; if (pUpstream pDownstream pFormat) { // find the upstream output pin with the specified format CComPtr IPin pIPinOutput = NULL; hr = GetPin(pUpstream, pFormat, PINDIR_OUTPUT, pIPinOutput); if (SUCCEEDED(hr)) { // get the downstream input pin CComPtr IPin pIPinInput = NULL; hr = GetPin(pDownstream, pFormat, PINDIR_INPUT, pIPinInput); if (SUCCEEDED(hr)) { // connect the pins hr = pGraph- Connect(pIPinOutput, pIPinInput); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // RenderFilter // Renders the named output pin of the filter, or the first unconnected output if // no name is provided HRESULT CDSUtils RenderFilter(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName) { HRESULT hr = S_OK; if (pUpstream) { CComPtr IPin pIPinOutput = NULL; if (pUpstreamPinName) { hr = GetPin(pUpstream, pUpstreamPinName, pIPinOutput); } else { hr = GetUnconnectedPin(pUpstream, PINDIR_OUTPUT, pIPinOutput); } if (SUCCEEDED(hr)) { hr = pGraph- Render(pIPinOutput); } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // DisconnectAllPins // Disconnect all the pins of the filters in a graph HRESULT CDSUtils DisconnectAllPins(IGraphBuilder* pGraph) { HRESULT hr = S_OK; if (pGraph) { CComPtr IEnumFilters pIEnumFilters = NULL; hr = pGraph- EnumFilters( pIEnumFilters); if (SUCCEEDED(hr)) { IBaseFilter* pFilter = NULL; while (S_OK == pIEnumFilters- Next(1, pFilter, NULL)) { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { IPin* pIPin = NULL; while (S_OK == pIEnumPins- Next(1, pIPin, NULL)) { IPin* pIPinConnection = NULL; if (S_OK == pIPin- ConnectedTo( pIPinConnection)) { // pins are connected, to disconnect filters, both pins must be disconnected hr = pGraph- Disconnect(pIPin); hr = pGraph- Disconnect(pIPinConnection); SAFE_RELEASE(pIPinConnection); } SAFE_RELEASE(pIPin); } } SAFE_RELEASE(pFilter); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // FindFilterInterface // Attempt to locate the specified interface HRESULT CDSUtils FindFilterInterface(IBaseFilter* pFilter, const IID riid, void** ppvInterface) { HRESULT hr = S_OK; if (pFilter ppvInterface) { hr = pFilter- QueryInterface(riid, ppvInterface); } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // FindPinInterface // Attempt to locate the interface on the named pin or on the first pin if no // name is provided. HRESULT CDSUtils FindPinInterface(IBaseFilter* pFilter, wchar_t* pName, const IID riid, void** ppvInterface) { HRESULT hr = S_OK; if (pFilter ppvInterface) { CComPtr IPin pIPin = NULL; if (pName) { hr = GetPin(pFilter, pName, pIPin); } else { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { hr = pIEnumPins- Next(1, pIPin, NULL); } } if (SUCCEEDED(hr)) { hr = pIPin- QueryInterface(riid, ppvInterface); } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // FindPinInterface // Attempt to locate the interface on the pin with the specified format or on the first pin if no // format is provided. HRESULT CDSUtils FindPinInterface(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, const IID riid, void** ppvInterface) { HRESULT hr = S_OK; if (pFilter ppvInterface) { CComPtr IPin pIPin = NULL; if (pFormat) { hr = GetPin(pFilter, pFormat, PinDir, pIPin); } else { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { hr = pIEnumPins- Next(1, pIPin, NULL); } } if (SUCCEEDED(hr)) { hr = pIPin- QueryInterface(riid, ppvInterface); } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // AddGraphToRot // Adds a DirectShow filter graph to the Running Object Table, // allowing GraphEdit to "spy" on a remote filter graph. HRESULT CDSUtils AddGraphToRot(IUnknown* pUnkGraph, DWORD* pdwRegister) { HRESULT hr = S_OK; if (pUnkGraph pdwRegister) { CComPtr IRunningObjectTable pROT = NULL; hr = GetRunningObjectTable(0, pROT); if (SUCCEEDED(hr)) { WCHAR wsz[128]; StringCchPrintfW(wsz, 128, L"FilterGraph %08x pid %08x\0", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); CComPtr IMoniker pMoniker = NULL; hr = CreateItemMoniker(L"!", wsz, pMoniker); if(SUCCEEDED(hr)) { // Use the ROTFLAGS_REGISTRATIONKEEPSALIVE to ensure a strong reference // to the object. Using this flag will cause the object to remain // registered until it is explicitly revoked with the Revoke() method. // // Not using this flag means that if GraphEdit remotely connects // to this graph and then GraphEdit exits, this object registration // will be deleted, causing future attempts by GraphEdit to fail until // this application is restarted or until the graph is registered again. hr = pROT- Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker, pdwRegister); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // RemoveGraphFromRot // Removes a filter graph from the Running Object Table void CDSUtils RemoveGraphFromRot(DWORD pdwRegister) { CComPtr IRunningObjectTable pROT = NULL; if (SUCCEEDED(GetRunningObjectTable(0, pROT))) { pROT- Revoke(pdwRegister); } } //------------------------------------------------------------------------------------ // CRegUtils - Registry utility class //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ // Constructor // CRegUtils CRegUtils() m_hKey(NULL) { } //------------------------------------------------------------------------------------ // Destructor // CRegUtils ~CRegUtils() { Close(); } //------------------------------------------------------------------------------------ // Open // Opens the specified subkey LONG CRegUtils Open(LPCTSTR lpSubKey) { Close(); m_subKeyName = "Software\\Blackmagic Design\\Samples\\"; m_subKeyName += lpSubKey; return RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_subKeyName.c_str(), 0, KEY_ALL_ACCESS, m_hKey); } //------------------------------------------------------------------------------------ // Create // Creates the specified subkey LONG CRegUtils Create(LPCTSTR lpSubKey) { Close(); m_subKeyName = "Software\\Blackmagic Design\\Samples\\"; m_subKeyName += lpSubKey; return RegCreateKeyEx(HKEY_LOCAL_MACHINE, m_subKeyName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, m_hKey, NULL); } //------------------------------------------------------------------------------------ // Close // Closes the subkey void CRegUtils Close() { RegCloseKey(m_hKey); m_hKey = NULL; m_subKeyName.empty(); } //------------------------------------------------------------------------------------ // SetString // Set the key for the named value of type string LONG CRegUtils SetString(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) { return RegSetValueEx(m_hKey, valueName, 0, REG_SZ, lpData, cbData); } //------------------------------------------------------------------------------------ // GetString // Query the key for the named value of type string LONG CRegUtils GetString(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) { LONG ret = ERROR_SUCCESS; DWORD size = cbData, type = 0; ret = RegQueryValueEx(m_hKey, valueName, NULL, type, lpData, size); if ((size != cbData) || (REG_SZ != type)) { ret = ERROR_INVALID_PARAMETER; } return ret; } //------------------------------------------------------------------------------------ // SetBinary // Set the key for the named value of type binary LONG CRegUtils SetBinary(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) { return RegSetValueEx(m_hKey, valueName, 0, REG_BINARY, lpData, cbData); } //------------------------------------------------------------------------------------ // GetBinary // Query the key for the named value of type binary LONG CRegUtils GetBinary(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) { LONG ret = ERROR_SUCCESS; DWORD size = cbData, type = 0; ret = RegQueryValueEx(m_hKey, valueName, NULL, type, lpData, size); if ((size != cbData) || (REG_BINARY != type)) { ret = ERROR_INVALID_PARAMETER; } return ret; } //------------------------------------------------------------------------------------ // SetDword // Set the key for the named value of type DWORD LONG CRegUtils SetDword(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) { return RegSetValueEx(m_hKey, valueName, 0, REG_DWORD, lpData, cbData); } //------------------------------------------------------------------------------------ // GetDword // Query the key for the named value of type DWORD LONG CRegUtils GetDword(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) { LONG ret = ERROR_SUCCESS; DWORD size = cbData, type = 0; ret = RegQueryValueEx(m_hKey, valueName, NULL, type, lpData, size); if ((size != cbData) || (REG_DWORD != type)) { ret = ERROR_INVALID_PARAMETER; } return ret; } //------------------------------------------------------------------------------------ // CUtils - utility class //------------------------------------------------------------------------------------ //----------------------------------------------------------------------------- // GetBMIHeader // Returns the BITMAPINFOHEADER structure from media type format extension BITMAPINFOHEADER* CUtils GetBMIHeader(const AM_MEDIA_TYPE* pamt) { BITMAPINFOHEADER* pbmih = NULL; if (pamt) { if (FORMAT_VideoInfo == pamt- formattype) { VIDEOINFOHEADER* pvih = reinterpret_cast VIDEOINFOHEADER* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER) = pamt- cbFormat); pbmih = pvih- bmiHeader; } else if (FORMAT_VideoInfo2 == pamt- formattype) { VIDEOINFOHEADER2* pvih = reinterpret_cast VIDEOINFOHEADER2* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER2) = pamt- cbFormat); pbmih = pvih- bmiHeader; } } return pbmih; } //----------------------------------------------------------------------------- // GetBMIHeader // Returns the BITMAPINFOHEADER structure from media type format extension BITMAPINFOHEADER* CUtils GetBMIHeader(const CMediaType mt) { BITMAPINFOHEADER* pbmih = NULL; if (FORMAT_VideoInfo == mt.formattype) { VIDEOINFOHEADER* pvih = reinterpret_cast VIDEOINFOHEADER* (mt.pbFormat); ASSERT(sizeof(VIDEOINFOHEADER) = mt.cbFormat); pbmih = pvih- bmiHeader; } else if (FORMAT_VideoInfo2 == mt.formattype) { VIDEOINFOHEADER2* pvih = reinterpret_cast VIDEOINFOHEADER2* (mt.pbFormat); ASSERT(sizeof(VIDEOINFOHEADER2) = mt.cbFormat); pbmih = pvih- bmiHeader; } return pbmih; } //----------------------------------------------------------------------------- // GetAvgTimePerFrame // Returns the average time per frame from media type format extension REFERENCE_TIME CUtils GetAvgTimePerFrame(const AM_MEDIA_TYPE* pamt) { REFERENCE_TIME rtAvgTimePerFrame = 0; if (pamt) { if (FORMAT_VideoInfo == pamt- formattype) { VIDEOINFOHEADER* pvih = reinterpret_cast VIDEOINFOHEADER* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER) = pamt- cbFormat); rtAvgTimePerFrame = pvih- AvgTimePerFrame; } else if (FORMAT_VideoInfo2 == pamt- formattype) { VIDEOINFOHEADER2* pvih = reinterpret_cast VIDEOINFOHEADER2* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER2) = pamt- cbFormat); rtAvgTimePerFrame = pvih- AvgTimePerFrame; } } return rtAvgTimePerFrame; } //------------------------------------------------------------------------------------ // GetImageSize // Calculates the image size unsigned long CUtils GetImageSize(BITMAPINFOHEADER* pbmih) { unsigned long dwImageSize = 0; if (pbmih) { switch (pbmih- biCompression) { default case BI_RGB dwImageSize = (pbmih- biWidth * abs(pbmih- biHeight) * pbmih- biBitCount) 3; break; case YVYU case 2YUY dwImageSize = (pbmih- biWidth * abs(pbmih- biHeight) * 16) 3; break; } } return dwImageSize; }
https://w.atwiki.jp/jikkyosha_ust/pages/399.html
The Acts of the Apostles (Ancient Greek Πράξεις τῶν Ἀποστόλων, Práxeis tôn Apostólōn; Latin Āctūs Apostolōrum), often referred to simply as Acts, is the fifth book of the New Testament; it tells of the founding of the Christian church and the spread of its message to the Roman empire.[1] Acts is the second half of a two-part work, referred to as Luke-Acts, by the same anonymous author, referred to as Luke the Evangelist, and usually dated to around 80-90 CE.[2][3] The first part, the Gospel of Luke, tells how God fulfilled his plan for the world s salvation through the life, death and resurrection of Jesus of Nazareth, the promised Messiah. Acts continues the story of Christianity in the 1st century, beginning with the Ascension of Christ. The early chapters, set in Jerusalem, describe the Day of Pentecost (the coming of the Holy Spirit) and the growth of the church in Jerusalem. Initially the Jews are receptive to the Christian message, but soon they turn against the followers of the Messiah. Rejected by the Jews, under the guidance of the Apostle Peter the message is taken to the Gentiles. The later chapters tell of Paul s conversion, his mission in Asia Minor and the Aegean, and finally his imprisonment in Rome, where, as the book ends, he awaits trial. Luke-Acts is an attempt to answer a theological problem, namely how the Messiah of the Jews came to have an overwhelmingly non-Jewish church; the answer it provides, and its central theme, is that the message of Christ was sent to the Gentiles because the Jews rejected it.[1] Contents [hide] 1 Composition and setting 1.1 Title, unity of Luke-Acts, authorship and date 1.2 Genre, sources and historicity of Acts 1.3 Audience and authorial intent 1.4 Manuscripts 2 Structure and content 2.1 Structure 2.2 Outline 2.3 Content 3 Theology 4 Comparison with other writings 4.1 Gospel of Luke 4.2 Pauline epistles 5 See also 6 References 7 Bibliography 8 External links Composition and setting[edit] Main article Authorship of Luke–Acts Ministry of the Apostles Russian icon by Fyodor Zubov, 1660 Title, unity of Luke-Acts, authorship and date[edit] The title "Acts of the Apostles" (Greek Πράξεις ἀποστόλων Praxeis Apostolon) was first used by Irenaeus in the late 2nd century. It is not known whether this was an existing title or one invented by Irenaeus; it does seem clear, however, that it was not given by the author.[4] The gospel of Luke and Acts make up a two-volume work which scholars call Luke-Acts.[3] Together they account for 27.5% of the New Testament, the largest contribution attributed to a single author, providing the framework for both the Church s liturgical calendar and the historical outline into which later generations have fitted their idea of the story of Jesus and the early church.[5] The author is not named in either volume.[6] According to Church tradition dating from the 2nd century, he was the "Luke" named as a companion of the apostle Paul in three of the letters attributed to Paul himself; this view is still sometimes advanced, but "a critical consensus emphasizes the countless contradictions between the account in Acts and the authentic Pauline letters."[7] (An example can be seen by comparing Acts accounts of Paul s conversion (Acts 9 1-31, 22 6-21, and 26 9-23) with Paul s own statement that he remained unknown to Christians in Judea after that event (Galatians 1 17-24).)[8] He admired Paul, but his theology was significantly different from Paul s on key points and he does not (in Acts) represent Paul s views accurately.[9] He was educated, a man of means, probably urban, and someone who respected manual work, although not a worker himself; this is significant, because more high-brow writers of the time looked down on the artisans and small business-people who made up the early church of Paul and were presumably Luke s audience.[10] The earliest possible date for the composition of Acts is set by the events with which it ends, Paul s imprisonment in Rome c.63 CE, but an early date is now rarely put forward.[11][12] The last possible date would be set by its first definite citation by another author, but there is no unanimity on this–some scholars find echoes of Acts in a work from c.95 CE called I Clement, while others see no indisputable citation until the middle of the 2nd century.[11] If Acts uses Josephus as a source, as has been proposed, then it must have been composed after 93 CE; it does not show any knowledge of Paul s letters, a fact which also supports a late date; and the social situation it reflects is one in which the faithful need "shepherds" to protect them from heretical (possibly Marcionite) "wolves", which again reflects a late date.[11] Most experts therefore date it to around 80-90 CE, although some suggest 90-110, [2] and there is evidence that it was still being substantially revised well into the 2nd century.[13] Genre, sources and historicity of Acts[edit] Luke (or more accurately the anonymous author of Luke-Acts) describes his work, Luke-Acts, as a "narrative" (diegesis). Acts, the second part, is widely thought of as a history, but it lacks exact analogies in Hellenistic or Jewish literature.[14] The title "Acts of the Apostles" (Praxeis Apostolon) would seem to identify it with the genre telling of the deeds and achievements of great men (praxeis), but it was not the title given by the author.[4] Luke seems to have taken as his model the works of two respected Classical authors, Dionysius of Halicarnassus, who wrote a well-known history of Rome, and the Jewish historian Josephus, author of a history of the Jews.[15] Like them he anchors his history by dating the birth of the founder (Romulus for Dionysius, Moses for Josephus, Jesus for Luke) and like them he tells how the founder is born from God, taught authoritatively, and appeared to witnesses after death before ascending to heaven.[15] By and large the sources for Acts can only be guessed at,[16] but Luke would have had access to the Septuagint (a Greek translation of the Jewish scriptures), the gospel of Mark and the collection of "sayings of Jesus" called the Q source.[17] He transposed a few incidents from Mark s gospel to the time of the Apostles – for example, the material about "clean" and "unclean" foods in Mark 7 is used in Acts 10, and Mark s account of the accusation that Jesus has attacked the Temple (Mark 14 58) is used in a story about Stephen (Acts 6 14).)[18] There are also points of contacts (meaning suggestive parallels but something less than clear evidence) with 1 Peter, the Letter to the Hebrews, and 1 Clement.[19] Other sources can only be inferred from internal evidence – the traditional explanation of the three "we" passages, for example, is that they represent eye-witness accounts.[20] The search for such inferred sources was popular in the 19th century, but by the mid-20th it had largely been abandoned.[21] Acts was read as a reliable history of the early church well into the post-Reformation era. By the 17th century, however, biblical scholars began to notice that it was incomplete and tendentious – its picture of a harmonious church is quite at odds with that given by Paul s letters, and it omits important events such as the deaths of both Peter and Paul. The mid-19th century scholar Ferdinand Baur suggested that Luke had re-written history to present a united Peter and Paul and advance a single orthodoxy against the Marcionites. (Marcion was a 2nd-century heretic who wished to cut Christianity off entirely from the Jews). Baur continues to have enormous influence, but today there is less interest in determining Luke s historical accuracy (although this has never died out) than in understanding his theological program.[22] Audience and authorial intent[edit] Luke was written to be read aloud to a group of Jesus-followers gathered in a house to share the Lord s supper.[15] The author assumes an educated Greek-speaking audience, but directs his attention to specifically Christian concerns rather than to the Greco-Roman world at large.[23] He begins his gospel with a preface addressed to Theophilus, informing him of his intention to provide an "ordered account" of events which will lead his reader to "certainty".[10] He did not write in order to provide Theophilus with historical justification – "did it happen?" – but to encourage faith – "what happened, and what does it all mean?"[24] Acts (or Luke-Acts) is intended as a work of "edification."[25] Edification means "the empirical demonstration that virtue is superior to vice,"[26] but is not all of Luke s purpose. He also engages with the question of a Christian s proper relationship with the Roman Empire, the civil power of the day could a Christian obey God and also Caesar? The answer is ambiguous.[27] The Romans never move against Jesus or his followers unless provoked by the Jews, in the trial scenes the Christian missionaries are always cleared of charges of violating Roman laws, and Acts ends with Paul in Rome proclaiming the Christian message under Roman protection; at the same time, Luke makes clear that the Romans, like all earthly rulers, receive their authority from Satan, while Christ is ruler of the kingdom of God. [28] Luke-Acts can be also seen as a defense of (or "apology" for) the Jesus movement addressed to the Jews the bulk of the speeches and sermons in Acts are addressed to Jewish audiences, with the Romans featuring as external arbiters on disputes concerning Jewish customs and law.[27] On the one hand Luke portrays the Christians as a sect of the Jews, and therefore entitled to legal protection as a recognised religion; on the other, Luke seems unclear as to the future God intends for Jews and Christians, celebrating the Jewishness of Jesus and his immediate followers while also stressing how the Jews had rejected God s promised Messiah.[29] Manuscripts[edit] There are two major textual variants of Luke-Acts, the Western text-type and the Alexandrian. The oldest complete Alexandrian manuscripts date from the 4th century and the oldest Western ones from the 6th, with fragments and citations going back to the 3rd. Western texts of Acts are 10% longer than Alexandrian texts, the additions tending to enhance the Jewish rejection of the Messiah and the role of the Holy Spirit, in ways that are stylistically different from the rest of Acts.[30] These conflicts suggest that Luke-Acts was still being substantially revised well into the 2nd century.[13] The majority of scholars prefer the Alexandrian (shorter) text-type over the Western as the more authentic, but this same argument would favour the Western over the Alexandrian for the gospel of Luke, as in that case the Western version is the shorter. The debate therefore continues.[30] Structure and content[edit] Acts 1 1-2a from the 14th century Minuscule 223 Structure[edit] Acts has two key structural principles. The first is the geographic movement from Jerusalem, centre of God s Covenantal people the Jews, to Rome, centre of the Gentile world. This structure reaches back to the author s preceding work, the Gospel of Luke, and is signaled by parallel scenes such as Paul s utterance in Acts 19 21, which echoes Jesus words 9 51 (Paul has Rome as his destination, as Jesus had Jerusalem). The second key element is the roles of Peter and Paul, the first representing the Jewish Christian church, the second the mission to the Gentiles.[31] Transition reprise of the preface addressed to Theophilus and the closing events of the gospel (Acts 1-1 26) Petrine Christianity the Jewish church from Jerusalem to Antioch (Acts 2 1-12 25) 2 1-8 1 - beginnings in Jerusalem 8 2-40 - the church expands to Samaria and beyond 9 1-31 - conversion of Paul 9 32-12 25 - the conversion of Cornelius, and the formation of the Antioch church Pauline Christianity the Gentile mission from Antioch to Rome (Acts 13 1-28 21) 13 1-14 28 - the Gentile mission is promoted from Antioch 15 1-35 - the Gentile mission is confirmed in Jerusalem 15 36-28 31 - the Gentile mission, climaxing in Paul s passion story in Rome (21 17-28 31) Outline[edit] Dedication to Theophilus (1 1–2) Resurrection appearances (1 3) Great Commission (1 4–8) Ascension (1 9) Second Coming Prophecy (1 10–11) Matthias replaced Judas (1 12–26) the Upper Room (1 13) Holy Spirit came at Pentecost (2), see also Paraclete Peter healed a crippled beggar (3 1–10) Peter s speech at the Temple (3 11–26) Peter and John before the Sanhedrin (4 1–22) Resurrection of the dead (4 2) Believers Prayer (4 23–31) Everything is shared (4 32–37) Ananias and Sapphira (5 1–11) Signs and Wonders (5 12–16) Apostles before the Sanhedrin (5 17–42) Seven Greeks appointed (6 1–7) Saint Stephen before the Sanhedrin (6 8–7 60) The "Cave of the Patriarchs" was located in Shechem (7 16) "Moses was educated in all the wisdom of the Egyptians" (7 22) First mentioning of Saul (Paul the Apostle) in the Bible (7 58) Paul the Apostle confesses his part in the martyrdom of Stephen (7 58-60) Saul persecuted the Church of Jerusalem (8 1–3) Philip the Evangelist (8 4–40) Simon Magus (8 9–24) Ethiopian eunuch (8 26–39) Conversion of Paul the Apostle (9 1–31, 22 1–22, 26 9–24) Paul the Apostle confesses his active part in the martyrdom of Stephen (22 20) Peter healed Aeneas and raised Tabitha from the dead (9 32–43) Conversion of Cornelius (10 1–8, 24–48) Peter s vision of a sheet with animals (10 9–23, 11 1–18) Church of Antioch founded (11 19–30) term "Christian" first used (11 26) Saint James the Great executed (12 1–2) Peter s rescue from prison (12 3–19) Death of Herod Agrippa I [in 44] (12 20–25) "the voice of a god" (12 22) Mission of Barnabas and Saul (13–14) "Saul, who was also known as Paul" (13 9) called "gods ... in human form" (14 11) Council of Jerusalem (15 1–35) Paul separated from Barnabas (15 36–41) 2nd and 3rd missions (16–20) Areopagus sermon (17 16-34) "God...has set a day" (17 30–31) Trial before Gallio c. 51–52 (18 12–17) Trip to Jerusalem (21) Before the people and the Sanhedrin (22–23) Before Felix–Festus–Agrippa II (24–26) Trip to Rome (27–28) called a god on Malta (28 6) Content[edit] See also Early Christianity and Jewish Christians The Gospel of Luke began with a prologue addressed to Theophilus; Acts likewise opens with an address to Theophilus and refers to "my earlier book", almost certainly the gospel. The apostles and other followers of Jesus meet and elect Matthias to replace Judas as a member of The Twelve. On Pentecost, the Holy Spirit descends and confers God s power on them, and Peter, along with John, preaches to many in Jerusalem, and performs Christ-like healings, casting out of evil spirits, and raising of the dead. At first many Jews follow Christ and are baptized, but the Christians begin to be increasingly persecuted by the Jews. Stephen is arrested for blasphemy, and after a trial, is found guilty and stoned by the Jews. Stephen s death marks a major turning point the Jews have rejected the message, and henceforth it will be taken to the Gentiles.[32] The message is taken to the Samaritans, a people rejected by Jews, and to the Gentiles. Saul of Tarsus, one of the Jews who persecuted the Christians, is converted by a vision to become a follower of Christ (an event which Luke regards as so important that he relates it three times). Peter, directed by a series of visions, preaches to Cornelius the Centurion, a Gentile God-fearer, who becomes a follower of Christ. The Holy Spirit descends on Peter and Cornelius, thus confirming that the message of eternal life in Christ is for all mankind. The Gentile church is established in Antioch (north-western Syria, the third-largest city of the empire), and here Christ s followers are first called Christians.[33] The mission to the Gentiles is promoted from Antioch and confirmed at meeting in Jerusalem between Paul and the leadership of the Jerusalem church. Paul spends the next few years traveling through western Asia Minor and the Aegean,preaching, converting Gentiles, and founding new churches. On a visit to Jerusalem he is set on by a Jewish mob. Saved by the Roman commander, he is accused by the Jews of being a revolutionary, the "ringleader of the sect of the Nazarenes", and imprisoned. Paul asserts his right as a Roman citizen, to be tried in Rome and is sent by sea to Rome, where he spends another two years under house arrest, proclaiming the Kingdom of God and teaching the "Lord Jesus Christ". Acts ends abruptly without recording the outcome of Paul s legal troubles.[citation needed] Theology[edit] Paul s conversion, from Livre d Heures d Étienne Chevalier (c. 1450–1460), Jean Fouquet, in the Château de Chantilly. Prior to the 1950s Luke-Acts was seen as a historical work, written to defend Christianity before the Romans or Paul against his detractors; since then, however, the tendency has been to see the work as primarily theological.[34] Luke s theology is expressed primarily through his overarching plot, the way scenes, themes and characters combine to construct his specific worldview.[35] His "salvation history" stretches from the Creation to the present time of his readers, in three ages first, the time of "the Law and the Prophets" (Luke 16 16), the period beginning with Genesis and ending with the appearance of John the Baptist (Luke 1 5-3 1); second, the epoch of Jesus, in which the Kingdom of God was preached (Luke 3 2-24 51); and finally the period of the Church, which began when the risen Christ was taken into Heaven, and would end with his second coming.[36] Luke-Acts is an attempt to answer a theological problem, namely how the Messiah promised to the Jews came to have an overwhelmingly non-Jewish church; the answer it provides, and its central theme, is that the message of Christ was sent to the Gentiles because the Jews rejected it.[1] This theme is introduced at the opening of the gospel of Luke, when Jesus, rejected in Nazareth, recalls that the prophets were rejected by Israel and accepted by Gentiles; at the end of the gospel he commands his disciples to preach his message to all nations, "beginning from Jerusalem." He repeats the command in Acts, telling them to preach "in Jerusalem, in all Judea and Samaria, and to the end of the Earth." They then proceed to do so, in the order outlined first Jerusalem, then Judea, then Samaria, then the entire (Roman) world.[37] For Luke, the Holy Spirit is the driving force behind the spread of the Christian message, and he places more emphasis on it than do any of the other evangelists. The Spirit is "poured out" at Pentecost, on the first Samaritan and Gentile believers, and on disciples who had been baptised only by John the Baptist, each time as a sign of God s approval. The Holy Spirit represents God s power (At his ascension, Jesus tells his followers, "You shall receive power when the Holy Spirit has come upon you") through it the disciples are given speech to convert thousands in Jerusalem, forming the first church (the term is used for the first time in Acts 5).[38] Comparison with other writings[edit] Saint Paul Writing His Epistles, ascribed to Valentin de Boulogne, 17th century Gospel of Luke[edit] As the second part of the two-part work Luke-Acts, Acts has significant links to the gospel of Luke. Major turning points in the structure of Acts, for example, find parallels in Luke the presentation of the child Jesus in the Temple parallels the opening of Acts in the Temple, Jesus forty days of testing in the wilderness prior to his mission parallel the forty days prior to his Ascension in Acts, the mission of Jesus in Samaria and the Decapolis (the lands of the Samaritans and Gentiles) parallels the missions of the Apostles in Samaria and the Gentile lands, and so on (see Gospel of Luke). These parallels continue through both books.[39] There are also differences between Luke and Acts, amounting at times to outright contradiction. For example, the gospel seems to place the Ascension on Easter Sunday, immediately after the Resurrection, while Acts 1 puts it forty days later.[40] There are similar conflicts over the theology. While not seriously questioning the single authorship of Luke-Acts, these differences do suggest the need for caution in seeking too much consistency in books written in essence as popular literature.[41] Pauline epistles[edit] Acts agrees with Paul s letters on the major outline of Paul s career as Saul he is converted and becomes Paul the Christian missionary and apostle, establishing new churches in Asia Minor and the Aegean and struggling to free Gentile Christians from the Jewish Law. There are also agreements on many incidents, such as Paul s escape from Damascus, where he is lowered down the walls in a basket. But details of these same incidents are frequently contradictory for example, according to Paul it was a pagan king who was trying to arrest him in Damascus, but according to Luke it was, characteristically, the Jews (2 Corinthians 11 33 and Acts 9 24). Many of the disagreements are not so immediately obvious Acts speaks of "Christians" and "disciples", but Paul never uses either term, and there are striking differences in the accounts of Paul s relationship with the Jerusalem church and its leaders (Acts 9-15 vs. Galatians 1-2). Acts omits much from the letters, notably Paul s problems with his congregations (internal difficulties are said to be the fault of the Jews instead), and his apparent final rejection by the church leaders in Jerusalem (Acts has Paul and Barnabas deliver an offering that is accepted, a trip that has no mention in the letters). There are also major differences between Acts on Paul on Christology (the understanding of Christ s nature), eschatology (understanding of the "last things"), and apostleship.[42] See also[edit] Historical reliability of the Acts of the Apostles List of Gospels List of omitted Bible verses Textual variants in the Acts of the Apostles Acts of the Apostles (genre) Acts of Andrew Acts of Barnabas Acts of John Acts of the Martyrs Acts of Paul Acts of Paul and Thecla Acts of Peter Acts of Peter and Paul Acts of Peter and the Twelve Acts of Pilate Acts of Philip Acts of Thomas Acts of Timothy The Lost Chapter of the Acts of the Apostles References[edit] ^ Jump up to a b c Burkett 2002, p. 263. ^ Jump up to a b Charlesworth 2008, p. no page number. ^ Jump up to a b Burkett 2002, p. 195. ^ Jump up to a b Matthews 2011, p. 12. Jump up ^ Boring 2012, p. 556. Jump up ^ Burkett 2002, p. 196. Jump up ^ Theissen Merz 1998, p. 32. Jump up ^ Perkins 1998, p. 253. Jump up ^ Boring 2012, p. 590. ^ Jump up to a b Green 1997, p. 35. ^ Jump up to a b c Boring 2012, p. 587. Jump up ^ Theissen Merz 1996 [tr. 1998], p. 32. ^ Jump up to a b Perkins 2009, p. 250-253. Jump up ^ Aune 1988, p. 77. ^ Jump up to a b c Balch 2003, p. 1104. Jump up ^ Bruce 1990, p. 40. Jump up ^ Boring 2012, p. 577. Jump up ^ Witherington 1998, p. 8. Jump up ^ Boring 2012, p. 578. Jump up ^ Bruce 1990, p. 40-41. Jump up ^ Boring 2012, p. 579. Jump up ^ Holladay 2011, p. no page numbers. Jump up ^ Green 1995, p. 16-17. Jump up ^ Green 1997, p. 36. Jump up ^ Fitzmyer 1998, p. 55-65. Jump up ^ Aune 1988, p. 80. ^ Jump up to a b Pickett 2011, p. 6-7. Jump up ^ Boring 2012, p. 562. Jump up ^ Boring 2012, p. 563. ^ Jump up to a b Thompson 2010, p. 332. Jump up ^ Boring 2012, p. 569-570. Jump up ^ Burkett 2002, p. 265. Jump up ^ Burkett 2002, p. 266. Jump up ^ Buckwalter 1996, p. 6. Jump up ^ Allen 2009, p. 326. Jump up ^ Evans 2011, p. no page numbers. Jump up ^ Burkett 2002, p. 264. Jump up ^ Burkett 2002, p. 268-270. Jump up ^ Tremmel 2011, p. 59. Jump up ^ Zwiep 2010, p. 39. Jump up ^ Parsons 1993, p. 17-18. Jump up ^ Boring 2012, p. 581, 588-590.The Acts of the Apostles (Ancient Greek Πράξεις τῶν Ἀποστόλων, Práxeis tôn Apostólōn; Latin Āctūs Apostolōrum), often referred to simply as Acts, is the fifth book of the New Testament; it tells of the founding of the Christian church and the spread of its message to the Roman empire.[1] Acts is the second half of a two-part work, referred to as Luke-Acts, by the same anonymous author, referred to as Luke the Evangelist, and usually dated to around 80-90 CE.[2][3] The first part, the Gospel of Luke, tells how God fulfilled his plan for the world s salvation through the life, death and resurrection of Jesus of Nazareth, the promised Messiah. Acts continues the story of Christianity in the 1st century, beginning with the Ascension of Christ. The early chapters, set in Jerusalem, describe the Day of Pentecost (the coming of the Holy Spirit) and the growth of the church in Jerusalem. Initially the Jews are receptive to the Christian message, but soon they turn against the followers of the Messiah. Rejected by the Jews, under the guidance of the Apostle Peter the message is taken to the Gentiles. The later chapters tell of Paul s conversion, his mission in Asia Minor and the Aegean, and finally his imprisonment in Rome, where, as the book ends, he awaits trial. Luke-Acts is an attempt to answer a theological problem, namely how the Messiah of the Jews came to have an overwhelmingly non-Jewish church; the answer it provides, and its central theme, is that the message of Christ was sent to the Gentiles because the Jews rejected it.[1] Contents [hide] 1 Composition and setting 1.1 Title, unity of Luke-Acts, authorship and date 1.2 Genre, sources and historicity of Acts 1.3 Audience and authorial intent 1.4 Manuscripts 2 Structure and content 2.1 Structure 2.2 Outline 2.3 Content 3 Theology 4 Comparison with other writings 4.1 Gospel of Luke 4.2 Pauline epistles 5 See also 6 References 7 Bibliography 8 External links Composition and setting[edit] Main article Authorship of Luke–Acts Ministry of the Apostles Russian icon by Fyodor Zubov, 1660 Title, unity of Luke-Acts, authorship and date[edit] The title "Acts of the Apostles" (Greek Πράξεις ἀποστόλων Praxeis Apostolon) was first used by Irenaeus in the late 2nd century. It is not known whether this was an existing title or one invented by Irenaeus; it does seem clear, however, that it was not given by the author.[4] The gospel of Luke and Acts make up a two-volume work which scholars call Luke-Acts.[3] Together they account for 27.5% of the New Testament, the largest contribution attributed to a single author, providing the framework for both the Church s liturgical calendar and the historical outline into which later generations have fitted their idea of the story of Jesus and the early church.[5] The author is not named in either volume.[6] According to Church tradition dating from the 2nd century, he was the "Luke" named as a companion of the apostle Paul in three of the letters attributed to Paul himself; this view is still sometimes advanced, but "a critical consensus emphasizes the countless contradictions between the account in Acts and the authentic Pauline letters."[7] (An example can be seen by comparing Acts accounts of Paul s conversion (Acts 9 1-31, 22 6-21, and 26 9-23) with Paul s own statement that he remained unknown to Christians in Judea after that event (Galatians 1 17-24).)[8] He admired Paul, but his theology was significantly different from Paul s on key points and he does not (in Acts) represent Paul s views accurately.[9] He was educated, a man of means, probably urban, and someone who respected manual work, although not a worker himself; this is significant, because more high-brow writers of the time looked down on the artisans and small business-people who made up the early church of Paul and were presumably Luke s audience.[10] The earliest possible date for the composition of Acts is set by the events with which it ends, Paul s imprisonment in Rome c.63 CE, but an early date is now rarely put forward.[11][12] The last possible date would be set by its first definite citation by another author, but there is no unanimity on this–some scholars find echoes of Acts in a work from c.95 CE called I Clement, while others see no indisputable citation until the middle of the 2nd century.[11] If Acts uses Josephus as a source, as has been proposed, then it must have been composed after 93 CE; it does not show any knowledge of Paul s letters, a fact which also supports a late date; and the social situation it reflects is one in which the faithful need "shepherds" to protect them from heretical (possibly Marcionite) "wolves", which again reflects a late date.[11] Most experts therefore date it to around 80-90 CE, although some suggest 90-110, [2] and there is evidence that it was still being substantially revised well into the 2nd century.[13] Genre, sources and historicity of Acts[edit] Luke (or more accurately the anonymous author of Luke-Acts) describes his work, Luke-Acts, as a "narrative" (diegesis). Acts, the second part, is widely thought of as a history, but it lacks exact analogies in Hellenistic or Jewish literature.[14] The title "Acts of the Apostles" (Praxeis Apostolon) would seem to identify it with the genre telling of the deeds and achievements of great men (praxeis), but it was not the title given by the author.[4] Luke seems to have taken as his model the works of two respected Classical authors, Dionysius of Halicarnassus, who wrote a well-known history of Rome, and the Jewish historian Josephus, author of a history of the Jews.[15] Like them he anchors his history by dating the birth of the founder (Romulus for Dionysius, Moses for Josephus, Jesus for Luke) and like them he tells how the founder is born from God, taught authoritatively, and appeared to witnesses after death before ascending to heaven.[15] By and large the sources for Acts can only be guessed at,[16] but Luke would have had access to the Septuagint (a Greek translation of the Jewish scriptures), the gospel of Mark and the collection of "sayings of Jesus" called the Q source.[17] He transposed a few incidents from Mark s gospel to the time of the Apostles – for example, the material about "clean" and "unclean" foods in Mark 7 is used in Acts 10, and Mark s account of the accusation that Jesus has attacked the Temple (Mark 14 58) is used in a story about Stephen (Acts 6 14).)[18] There are also points of contacts (meaning suggestive parallels but something less than clear evidence) with 1 Peter, the Letter to the Hebrews, and 1 Clement.[19] Other sources can only be inferred from internal evidence – the traditional explanation of the three "we" passages, for example, is that they represent eye-witness accounts.[20] The search for such inferred sources was popular in the 19th century, but by the mid-20th it had largely been abandoned.[21] Acts was read as a reliable history of the early church well into the post-Reformation era. By the 17th century, however, biblical scholars began to notice that it was incomplete and tendentious – its picture of a harmonious church is quite at odds with that given by Paul s letters, and it omits important events such as the deaths of both Peter and Paul. The mid-19th century scholar Ferdinand Baur suggested that Luke had re-written history to present a united Peter and Paul and advance a single orthodoxy against the Marcionites. (Marcion was a 2nd-century heretic who wished to cut Christianity off entirely from the Jews). Baur continues to have enormous influence, but today there is less interest in determining Luke s historical accuracy (although this has never died out) than in understanding his theological program.[22] Audience and authorial intent[edit] Luke was written to be read aloud to a group of Jesus-followers gathered in a house to share the Lord s supper.[15] The author assumes an educated Greek-speaking audience, but directs his attention to specifically Christian concerns rather than to the Greco-Roman world at large.[23] He begins his gospel with a preface addressed to Theophilus, informing him of his intention to provide an "ordered account" of events which will lead his reader to "certainty".[10] He did not write in order to provide Theophilus with historical justification – "did it happen?" – but to encourage faith – "what happened, and what does it all mean?"[24] Acts (or Luke-Acts) is intended as a work of "edification."[25] Edification means "the empirical demonstration that virtue is superior to vice,"[26] but is not all of Luke s purpose. He also engages with the question of a Christian s proper relationship with the Roman Empire, the civil power of the day could a Christian obey God and also Caesar? The answer is ambiguous.[27] The Romans never move against Jesus or his followers unless provoked by the Jews, in the trial scenes the Christian missionaries are always cleared of charges of violating Roman laws, and Acts ends with Paul in Rome proclaiming the Christian message under Roman protection; at the same time, Luke makes clear that the Romans, like all earthly rulers, receive their authority from Satan, while Christ is ruler of the kingdom of God. [28] Luke-Acts can be also seen as a defense of (or "apology" for) the Jesus movement addressed to the Jews the bulk of the speeches and sermons in Acts are addressed to Jewish audiences, with the Romans featuring as external arbiters on disputes concerning Jewish customs and law.[27] On the one hand Luke portrays the Christians as a sect of the Jews, and therefore entitled to legal protection as a recognised religion; on the other, Luke seems unclear as to the future God intends for Jews and Christians, celebrating the Jewishness of Jesus and his immediate followers while also stressing how the Jews had rejected God s promised Messiah.[29] Manuscripts[edit] There are two major textual variants of Luke-Acts, the Western text-type and the Alexandrian. The oldest complete Alexandrian manuscripts date from the 4th century and the oldest Western ones from the 6th, with fragments and citations going back to the 3rd. Western texts of Acts are 10% longer than Alexandrian texts, the additions tending to enhance the Jewish rejection of the Messiah and the role of the Holy Spirit, in ways that are stylistically different from the rest of Acts.[30] These conflicts suggest that Luke-Acts was still being substantially revised well into the 2nd century.[13] The majority of scholars prefer the Alexandrian (shorter) text-type over the Western as the more authentic, but this same argument would favour the Western over the Alexandrian for the gospel of Luke, as in that case the Western version is the shorter. The debate therefore continues.[30] Structure and content[edit] Acts 1 1-2a from the 14th century Minuscule 223 Structure[edit] Acts has two key structural principles. The first is the geographic movement from Jerusalem, centre of God s Covenantal people the Jews, to Rome, centre of the Gentile world. This structure reaches back to the author s preceding work, the Gospel of Luke, and is signaled by parallel scenes such as Paul s utterance in Acts 19 21, which echoes Jesus words 9 51 (Paul has Rome as his destination, as Jesus had Jerusalem). The second key element is the roles of Peter and Paul, the first representing the Jewish Christian church, the second the mission to the Gentiles.[31] Transition reprise of the preface addressed to Theophilus and the closing events of the gospel (Acts 1-1 26) Petrine Christianity the Jewish church from Jerusalem to Antioch (Acts 2 1-12 25) 2 1-8 1 - beginnings in Jerusalem 8 2-40 - the church expands to Samaria and beyond 9 1-31 - conversion of Paul 9 32-12 25 - the conversion of Cornelius, and the formation of the Antioch church Pauline Christianity the Gentile mission from Antioch to Rome (Acts 13 1-28 21) 13 1-14 28 - the Gentile mission is promoted from Antioch 15 1-35 - the Gentile mission is confirmed in Jerusalem 15 36-28 31 - the Gentile mission, climaxing in Paul s passion story in Rome (21 17-28 31) Outline[edit] Dedication to Theophilus (1 1–2) Resurrection appearances (1 3) Great Commission (1 4–8) Ascension (1 9) Second Coming Prophecy (1 10–11) Matthias replaced Judas (1 12–26) the Upper Room (1 13) Holy Spirit came at Pentecost (2), see also Paraclete Peter healed a crippled beggar (3 1–10) Peter s speech at the Temple (3 11–26) Peter and John before the Sanhedrin (4 1–22) Resurrection of the dead (4 2) Believers Prayer (4 23–31) Everything is shared (4 32–37) Ananias and Sapphira (5 1–11) Signs and Wonders (5 12–16) Apostles before the Sanhedrin (5 17–42) Seven Greeks appointed (6 1–7) Saint Stephen before the Sanhedrin (6 8–7 60) The "Cave of the Patriarchs" was located in Shechem (7 16) "Moses was educated in all the wisdom of the Egyptians" (7 22) First mentioning of Saul (Paul the Apostle) in the Bible (7 58) Paul the Apostle confesses his part in the martyrdom of Stephen (7 58-60) Saul persecuted the Church of Jerusalem (8 1–3) Philip the Evangelist (8 4–40) Simon Magus (8 9–24) Ethiopian eunuch (8 26–39) Conversion of Paul the Apostle (9 1–31, 22 1–22, 26 9–24) Paul the Apostle confesses his active part in the martyrdom of Stephen (22 20) Peter healed Aeneas and raised Tabitha from the dead (9 32–43) Conversion of Cornelius (10 1–8, 24–48) Peter s vision of a sheet with animals (10 9–23, 11 1–18) Church of Antioch founded (11 19–30) term "Christian" first used (11 26) Saint James the Great executed (12 1–2) Peter s rescue from prison (12 3–19) Death of Herod Agrippa I [in 44] (12 20–25) "the voice of a god" (12 22) Mission of Barnabas and Saul (13–14) "Saul, who was also known as Paul" (13 9) called "gods ... in human form" (14 11) Council of Jerusalem (15 1–35) Paul separated from Barnabas (15 36–41) 2nd and 3rd missions (16–20) Areopagus sermon (17 16-34) "God...has set a day" (17 30–31) Trial before Gallio c. 51–52 (18 12–17) Trip to Jerusalem (21) Before the people and the Sanhedrin (22–23) Before Felix–Festus–Agrippa II (24–26) Trip to Rome (27–28) called a god on Malta (28 6) Content[edit] See also Early Christianity and Jewish Christians The Gospel of Luke began with a prologue addressed to Theophilus; Acts likewise opens with an address to Theophilus and refers to "my earlier book", almost certainly the gospel. The apostles and other followers of Jesus meet and elect Matthias to replace Judas as a member of The Twelve. On Pentecost, the Holy Spirit descends and confers God s power on them, and Peter, along with John, preaches to many in Jerusalem, and performs Christ-like healings, casting out of evil spirits, and raising of the dead. At first many Jews follow Christ and are baptized, but the Christians begin to be increasingly persecuted by the Jews. Stephen is arrested for blasphemy, and after a trial, is found guilty and stoned by the Jews. Stephen s death marks a major turning point the Jews have rejected the message, and henceforth it will be taken to the Gentiles.[32] The message is taken to the Samaritans, a people rejected by Jews, and to the Gentiles. Saul of Tarsus, one of the Jews who persecuted the Christians, is converted by a vision to become a follower of Christ (an event which Luke regards as so important that he relates it three times). Peter, directed by a series of visions, preaches to Cornelius the Centurion, a Gentile God-fearer, who becomes a follower of Christ. The Holy Spirit descends on Peter and Cornelius, thus confirming that the message of eternal life in Christ is for all mankind. The Gentile church is established in Antioch (north-western Syria, the third-largest city of the empire), and here Christ s followers are first called Christians.[33] The mission to the Gentiles is promoted from Antioch and confirmed at meeting in Jerusalem between Paul and the leadership of the Jerusalem church. Paul spends the next few years traveling through western Asia Minor and the Aegean,preaching, converting Gentiles, and founding new churches. On a visit to Jerusalem he is set on by a Jewish mob. Saved by the Roman commander, he is accused by the Jews of being a revolutionary, the "ringleader of the sect of the Nazarenes", and imprisoned. Paul asserts his right as a Roman citizen, to be tried in Rome and is sent by sea to Rome, where he spends another two years under house arrest, proclaiming the Kingdom of God and teaching the "Lord Jesus Christ". Acts ends abruptly without recording the outcome of Paul s legal troubles.[citation needed] Theology[edit] Paul s conversion, from Livre d Heures d Étienne Chevalier (c. 1450–1460), Jean Fouquet, in the Château de Chantilly. Prior to the 1950s Luke-Acts was seen as a historical work, written to defend Christianity before the Romans or Paul against his detractors; since then, however, the tendency has been to see the work as primarily theological.[34] Luke s theology is expressed primarily through his overarching plot, the way scenes, themes and characters combine to construct his specific worldview.[35] His "salvation history" stretches from the Creation to the present time of his readers, in three ages first, the time of "the Law and the Prophets" (Luke 16 16), the period beginning with Genesis and ending with the appearance of John the Baptist (Luke 1 5-3 1); second, the epoch of Jesus, in which the Kingdom of God was preached (Luke 3 2-24 51); and finally the period of the Church, which began when the risen Christ was taken into Heaven, and would end with his second coming.[36] Luke-Acts is an attempt to answer a theological problem, namely how the Messiah promised to the Jews came to have an overwhelmingly non-Jewish church; the answer it provides, and its central theme, is that the message of Christ was sent to the Gentiles because the Jews rejected it.[1] This theme is introduced at the opening of the gospel of Luke, when Jesus, rejected in Nazareth, recalls that the prophets were rejected by Israel and accepted by Gentiles; at the end of the gospel he commands his disciples to preach his message to all nations, "beginning from Jerusalem." He repeats the command in Acts, telling them to preach "in Jerusalem, in all Judea and Samaria, and to the end of the Earth." They then proceed to do so, in the order outlined first Jerusalem, then Judea, then Samaria, then the entire (Roman) world.[37] For Luke, the Holy Spirit is the driving force behind the spread of the Christian message, and he places more emphasis on it than do any of the other evangelists. The Spirit is "poured out" at Pentecost, on the first Samaritan and Gentile believers, and on disciples who had been baptised only by John the Baptist, each time as a sign of God s approval. The Holy Spirit represents God s power (At his ascension, Jesus tells his followers, "You shall receive power when the Holy Spirit has come upon you") through it the disciples are given speech to convert thousands in Jerusalem, forming the first church (the term is used for the first time in Acts 5).[38] Comparison with other writings[edit] Saint Paul Writing His Epistles, ascribed to Valentin de Boulogne, 17th century Gospel of Luke[edit] As the second part of the two-part work Luke-Acts, Acts has significant links to the gospel of Luke. Major turning points in the structure of Acts, for example, find parallels in Luke the presentation of the child Jesus in the Temple parallels the opening of Acts in the Temple, Jesus forty days of testing in the wilderness prior to his mission parallel the forty days prior to his Ascension in Acts, the mission of Jesus in Samaria and the Decapolis (the lands of the Samaritans and Gentiles) parallels the missions of the Apostles in Samaria and the Gentile lands, and so on (see Gospel of Luke). These parallels continue through both books.[39] There are also differences between Luke and Acts, amounting at times to outright contradiction. For example, the gospel seems to place the Ascension on Easter Sunday, immediately after the Resurrection, while Acts 1 puts it forty days later.[40] There are similar conflicts over the theology. While not seriously questioning the single authorship of Luke-Acts, these differences do suggest the need for caution in seeking too much consistency in books written in essence as popular literature.[41] Pauline epistles[edit] Acts agrees with Paul s letters on the major outline of Paul s career as Saul he is converted and becomes Paul the Christian missionary and apostle, establishing new churches in Asia Minor and the Aegean and struggling to free Gentile Christians from the Jewish Law. There are also agreements on many incidents, such as Paul s escape from Damascus, where he is lowered down the walls in a basket. But details of these same incidents are frequently contradictory for example, according to Paul it was a pagan king who was trying to arrest him in Damascus, but according to Luke it was, characteristically, the Jews (2 Corinthians 11 33 and Acts 9 24). Many of the disagreements are not so immediately obvious Acts speaks of "Christians" and "disciples", but Paul never uses either term, and there are striking differences in the accounts of Paul s relationship with the Jerusalem church and its leaders (Acts 9-15 vs. Galatians 1-2). Acts omits much from the letters, notably Paul s problems with his congregations (internal difficulties are said to be the fault of the Jews instead), and his apparent final rejection by the church leaders in Jerusalem (Acts has Paul and Barnabas deliver an offering that is accepted, a trip that has no mention in the letters). There are also major differences between Acts on Paul on Christology (the understanding of Christ s nature), eschatology (understanding of the "last things"), and apostleship.[42] See also[edit] Historical reliability of the Acts of the Apostles List of Gospels List of omitted Bible verses Textual variants in the Acts of the Apostles Acts of the Apostles (genre) Acts of Andrew Acts of Barnabas Acts of John Acts of the Martyrs Acts of Paul Acts of Paul and Thecla Acts of Peter Acts of Peter and Paul Acts of Peter and the Twelve Acts of Pilate Acts of Philip Acts of Thomas Acts of Timothy The Lost Chapter of the Acts of the Apostles References[edit] ^ Jump up to a b c Burkett 2002, p. 263. ^ Jump up to a b Charlesworth 2008, p. no page number. ^ Jump up to a b Burkett 2002, p. 195. ^ Jump up to a b Matthews 2011, p. 12. Jump up ^ Boring 2012, p. 556. Jump up ^ Burkett 2002, p. 196. Jump up ^ Theissen Merz 1998, p. 32. Jump up ^ Perkins 1998, p. 253. Jump up ^ Boring 2012, p. 590. ^ Jump up to a b Green 1997, p. 35. ^ Jump up to a b c Boring 2012, p. 587. Jump up ^ Theissen Merz 1996 [tr. 1998], p. 32. ^ Jump up to a b Perkins 2009, p. 250-253. Jump up ^ Aune 1988, p. 77. ^ Jump up to a b c Balch 2003, p. 1104. Jump up ^ Bruce 1990, p. 40. Jump up ^ Boring 2012, p. 577. Jump up ^ Witherington 1998, p. 8. Jump up ^ Boring 2012, p. 578. Jump up ^ Bruce 1990, p. 40-41. Jump up ^ Boring 2012, p. 579. Jump up ^ Holladay 2011, p. no page numbers. Jump up ^ Green 1995, p. 16-17. Jump up ^ Green 1997, p. 36. Jump up ^ Fitzmyer 1998, p. 55-65. Jump up ^ Aune 1988, p. 80. ^ Jump up to a b Pickett 2011, p. 6-7. Jump up ^ Boring 2012, p. 562. Jump up ^ Boring 2012, p. 563. ^ Jump up to a b Thompson 2010, p. 332. Jump up ^ Boring 2012, p. 569-570. Jump up ^ Burkett 2002, p. 265. Jump up ^ Burkett 2002, p. 266. Jump up ^ Buckwalter 1996, p. 6. Jump up ^ Allen 2009, p. 326. Jump up ^ Evans 2011, p. no page numbers. Jump up ^ Burkett 2002, p. 264. Jump up ^ Burkett 2002, p. 268-270. Jump up ^ Tremmel 2011, p. 59. Jump up ^ Zwiep 2010, p. 39. Jump up ^ Parsons 1993, p. 17-18. Jump up ^ Boring 2012, p. 581, 588-590.
https://w.atwiki.jp/ketcindy-eng/pages/24.html
Modified Sep. 1st 2016 Setting up KeTCindy in case when all software are installed for the first time Firstly, download and ungzip "InstallforMac" and "KeTCindy" onto your Desktop. 1) Copy InstallforMac.dmg and ketcindy.zip to Desktop. 2) Unzip ketcindy.zip and Double click InstallforMac.dmg to make the disk image. 3) Installing TeX Open installforMac, and copy kettex forlder into "/Applications/KeTCindy". 4) Installing Scilab5.5.2 Extract "scilab-5.5.2-x86_64.dmg" by double clicking and put the resulting "Scilab-5.5.2" into /Applications. Rmk You don t need any java upgrade only for KeTCindy. 5) Installing Cinderella2 Copy "Cinderella2.zip" and paste it into desktop. Extract it by double clicking and put into /Applications. Rmk In case when the warning "There is no Java" appears, update Java. 6) Setting up KeTCindy (a) Copy ketcindy folder into /Users/(name)/ (b) Double click "template.cdy", then Cinderella2 will launch. (c) Choose "Reveal Plugin Folder" from "Script" menu. (d) Paste a file KetcindyPlugin.jar in ketjava into folder "Plugins". (e) Close Cinderella2 once. RMK Don t delete the folders and files originally contained in "Plugins". 7) Use of CindyScript (1) Open "tmplate.cdy" in "KeTCindy" in your home directory by double clicking. (2) Choose "Scripting"= "Edit Cindyscript" from top menu. (3) In the slot "draw"= "figures", generate and modify figures. (4) Push the GEAR mark in the top menu. 8) Push "Texview" and "Exekc" button sequentially. Then, Scilab and TeX are succesively executed, and the final PDF output is displayed. 9) If you use texworks as a editor of TeX, (1) Launch TeXworks, and choose Edit Preference Typeset (2) Set as follows Push + name texworkslatex program find; /Applications/kettex/ketbin/texworkslatex.sh Argument $fullname
https://w.atwiki.jp/shin-b/pages/23.html
設定ファイルのデフォルトファイル名を変更する方法 System.setPropertyでファイル名を指定するとよい System.setProperty("log4j.configuration", "xxxxx-log4j.properties"); ↑ファイル名